鸿蒙HarmonyOS应用开发之使用Node-API接口进行异步任务开发

场景介绍

napi_create_async_work是Node-API接口之一,用于创建一个异步工作对象。可以在需要执行耗时操作的场景中使用,以避免阻塞主线程,确保应用程序的性能和响应性能。例如以下场景:

  • 文件操作:读取大型文件或执行复杂的文件操作时,可以使用异步工作对象来避免阻塞主线程。

  • 网络请求:当需要进行网络请求并等待响应时,使用异步工作对象可以确保主线程不被阻塞,从而提高应用程序的响应性能。

  • 数据库操作:当需要执行复杂的数据库查询或写入操作时,使用异步工作对象可以确保主线程不被阻塞,从而提高应用程序的并发性能。

  • 图像处理:当需要对大型图像进行处理或执行复杂的图像算法时,使用异步工作对象可以确保主线程不被阻塞,从而提高应用程序的实时性能。

异步调用支持callback方式和Promise方式,使用哪种方式由应用开发者决定,通过是否传递callback函数进行区分。

使用Promise方式示例

  1. 使用napi_create_async_work创建异步任务,并使用napi_queue_async_work将异步任务加入队列,等待执行。
struct CallbackData {
    napi_async_work asyncWork = nullptr;
    napi_deferred deferred = nullptr;
    napi_ref callback = nullptr;
    double args = 0;
    double result = 0;
};

static napi_value AsyncWork(napi_env env, napi_callback_info info)
{
   size_t argc = 1;
   napi_value args[1];
   napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

   napi_value promise = nullptr;
   napi_deferred deferred = nullptr;
   napi_create_promise(env, &deferred, &promise);

   auto callbackData = new CallbackData();
   callbackData->deferred = deferred;
   napi_get_value_double(env, args[0], &callbackData->args);

   napi_value resourceName = nullptr;
   napi_create_string_utf8(env, "AsyncCallback", NAPI_AUTO_LENGTH, &resourceName);
   // 创建异步任务
   napi_create_async_work(env, nullptr, resourceName, ExecuteCB, CompleteCB, callbackData, &callbackData->asyncWork);
   // 将异步任务加入队列
   napi_queue_async_work(env, callbackData->asyncWork);

   return promise;
}
  1. 定义异步任务的第一个回调函数,该函数在工作线程中执行,处理具体的业务逻辑。
static void ExecuteCB(napi_env env, void *data)
{
    CallbackData *callbackData = reinterpret_cast<CallbackData *>(data);
    callbackData->result = callbackData->args;
}
  1. 定义异步任务的第二个回调函数,该函数在主线程执行,将结果传递给ArkTS侧。
static void CompleteCB(napi_env env, napi_status status, void *data)
{
    CallbackData *callbackData = reinterpret_cast<CallbackData *>(data);
    napi_value result = nullptr;
    napi_create_double(env, callbackData->result, &result);
    if (callbackData->result > 0) {
        napi_resolve_deferred(env, callbackData->deferred, result);
    } else {
        napi_reject_deferred(env, callbackData->deferred, result);
    }

    napi_delete_async_work(env, callbackData->asyncWork);
    delete callbackData;
}
  1. 模块初始化以及ArkTS侧调用接口。
// 模块初始化
static napi_value Init(napi_env env, napi_value exports)
{
    napi_property_descriptor desc[] = {
        { "asyncWork", nullptr, AsyncWork, nullptr, nullptr, nullptr, napi_default, nullptr }
    };
    napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
    return exports;
}

// ArkTS侧调用接口
nativeModule.asyncWork(1024).then((result) => {
    hilog.info(0x0000, 'XXX', 'result is %{public}d', result);
  }
);

使用callback方式示例

  1. 使用napi_create_async_work创建异步任务,并使用napi_queue_async_work将异步任务加入队列,等待执行。
struct CallbackData {
  napi_async_work asyncWork = nullptr;
  napi_ref callbackRef = nullptr;
  double args[2] = {0};
  double result = 0;
};

napi_value AsyncWork(napi_env env, napi_callback_info info) 
{
    size_t argc = 3;
    napi_value args[3];
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
    auto asyncContext = new CallbackData();
    // 将接收到的参数保存到callbackData
    napi_get_value_double(env, args[0], &asyncContext->args[0]);
    napi_get_value_double(env, args[1], &asyncContext->args[1]);
    // 将传入的callback转换为napi_ref延长其生命周期,防止被GC掉
    napi_create_reference(env, args[2], 1, &asyncContext->callbackRef);
    napi_value resourceName = nullptr;
    napi_create_string_utf8(env, "asyncWorkCallback", NAPI_AUTO_LENGTH, &resourceName);
    // 创建异步任务
    napi_create_async_work(env, nullptr, resourceName, ExecuteCB, CompleteCB, 
                           asyncContext, &asyncContext->asyncWork); 
    // 将异步任务加入队列
    napi_queue_async_work(env, asyncContext->asyncWork);
    return nullptr;
}
  1. 定义异步任务的第一个回调函数,该函数在工作线程中执行,处理具体的业务逻辑。
static void ExecuteCB(napi_env env, void *data) 
{
    CallbackData *callbackData = reinterpret_cast<CallbackData *>(data);
    callbackData->result = callbackData->args[0] + callbackData->args[1];
}
  1. 定义异步任务的第二个回调函数,该函数在主线程执行,将结果传递给ArkTS侧。
static void CompleteCB(napi_env env, napi_status status, void *data) 
{
    CallbackData *callbackData = reinterpret_cast<CallbackData *>(data);
    napi_value callbackArg[1] = {nullptr};
    napi_create_double(env, callbackData->result, &callbackArg[0]);
    napi_value callback = nullptr;
    napi_get_reference_value(env, callbackData->callbackRef, &callback);
    // 执行回调函数
    napi_value result;
    napi_value undefined;
    napi_get_undefined(env, &undefined);
    napi_call_function(env, undefined, callback, 1, callbackArg, &result);
    // 删除napi_ref对象以及异步任务
    napi_delete_reference(env, callbackData->callbackRef);
    napi_delete_async_work(env, callbackData->asyncWork);
    delete callbackData;
}
  1. 模块初始化以及ArkTS侧调用接口。
// 模块初始化
static napi_value Init(napi_env env, napi_value exports)
{
    napi_property_descriptor desc[] = {
        { "asyncWork", nullptr, AsyncWork, nullptr, nullptr, nullptr, napi_default, nullptr }
    };
    napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
    return exports;
}

// ArkTS侧调用接口
let num1: number = 123;
let num2: number = 456;
nativeModule.asyncWork(num1, num2, (result) => {
  hilog.info(0x0000, 'XXX', 'result is %{public}d', result);
}); 

为了能让大家更好的学习鸿蒙(HarmonyOS NEXT)开发技术,这边特意整理了《鸿蒙开发学习手册》(共计890页),希望对大家有所帮助:https://qr21.cn/FV7h05

《鸿蒙开发学习手册》:

如何快速入门:https://qr21.cn/FV7h05

  1. 基本概念
  2. 构建第一个ArkTS应用
  3. ……

开发基础知识:https://qr21.cn/FV7h05

  1. 应用基础知识
  2. 配置文件
  3. 应用数据管理
  4. 应用安全管理
  5. 应用隐私保护
  6. 三方应用调用管控机制
  7. 资源分类与访问
  8. 学习ArkTS语言
  9. ……

基于ArkTS 开发:https://qr21.cn/FV7h05

  1. Ability开发
  2. UI开发
  3. 公共事件与通知
  4. 窗口管理
  5. 媒体
  6. 安全
  7. 网络与链接
  8. 电话服务
  9. 数据管理
  10. 后台任务(Background Task)管理
  11. 设备管理
  12. 设备使用信息统计
  13. DFX
  14. 国际化开发
  15. 折叠屏系列
  16. ……

鸿蒙开发面试真题(含参考答案):https://qr18.cn/F781PH

鸿蒙开发面试大盘集篇(共计319页):https://qr18.cn/F781PH

1.项目开发必备面试题
2.性能优化方向
3.架构方向
4.鸿蒙开发系统底层方向
5.鸿蒙音视频开发方向
6.鸿蒙车载开发方向
7.鸿蒙南向开发方向

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/492737.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

朋友圈运营攻略,还有多号群发朋友圈教程

为什么需要打造朋友圈&#xff1f; 私域朋友圈运营运营者和私域流量理论上其实就是“网友”的关系 要维持稳定的社交关系&#xff0c;做好私域流量运营&#xff0c;就必须持续地进行自身价值塑造&#xff01;而朋友圈就是最好的“战场” 打造优质朋友圈的关键点&#xff1a; …

09 网络ARP请求,响应,ICMP协议

arp协议_arp请求_arp回应 ICMP包构造ping搜狐服务器参考 #include <stdio.h> #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> #include <linux/if_packet.h> #include <linux/if_ether.h> #include <string.h> #includ…

文案转化率低?快看看这两个坑你踩没踩

对于很多中小企业来说&#xff0c;无论是来拓市场还是获客&#xff0c;软文营销都会成为他们的主要营销方式&#xff0c;比较软文营销的成本较低&#xff0c;同时门槛也不高。但是也有品牌发现&#xff0c;自己和团队辛苦构思了几周写出的文案&#xff0c;但是效果不是很好。今…

五、Elasticsearch 集成

目录 5.1 Spring Data 框架集成5.1.1 Spring Data 框架介绍5.1.2 Spring Data Elasticsearch 介绍5.1.3 Spring Data Elasticsearch 版本对比5.1.4 集成步骤 5.1 Spring Data 框架集成 5.1.1 Spring Data 框架介绍 Spring Data 是一个用于简化数据库开发的开源框架。其主要目…

前端 CSS 经典:grid 栅格布局

前言&#xff1a;Grid 布局是将容器划分成"行"和"列"&#xff0c;产生单元格&#xff0c;然后将"项目"分配给划分好的单元格&#xff0c;因为有行和列&#xff0c;可以看作是二维布局。 一 术语 1. 容器 采用网格布局的区域&#xff0c;也就是…

【机器学习之旅】概念启程、步骤前行、分类掌握与实践落地

&#x1f388;个人主页&#xff1a;豌豆射手^ &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;机器学习 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进…

六、保持长期高效的七个法则(二)Rules for Staying Productive Long-Term(2)

Rule #5 - If your work changes, your system should too. 准则五&#xff1a;如果你的工作变了&#xff0c;你的系统也应该改变。 For some, work will be consistent enough to not need major changes.You simply stick to the same system and you’ll get the results y…

高精密基准源 国产替代 REF191 ADR4520 ADR420 ADR430 ADR440 REF5020 MAX6126

高精密基准源 国产替代 REF191 ADR4520 ADR420 ADR430 ADR440 REF5020 MAX6126 ADR03 REF03 REF192 AD580 AD780 ADR441 ADR4525 ADR431 ADR421 REF5025ADR423 ADR433 ADR443 ADR4530 REF193 AD780 ADR06 REF5030ADR434 ADR444 ADR4540 REF198 REF5040ADR425 ADR435 ADR445 AD…

成功推出全新生成式AI的四大原则

生成式AI有望从根本上打开一扇新世界机遇的大门&#xff0c;以满足各行各业的客户需求。从提供个性化回复的对话式聊天机器人&#xff0c;到各种应用的代码&#xff0c;再到营销传播的目标内容&#xff0c;生成式AI正在彻底改变企业的运作方式。为竞相提供卓越的客户体验&#…

分布式系统的发展史

目录 &#x1f433;今日良言&#xff1a;且视他人之疑目如盏盏鬼火&#xff0c;大胆地去走自己的夜路 &#x1f407;一、常见概念 &#x1f407;二、发展史 今日良言&#xff1a;且视他人之疑目如盏盏鬼火&#xff0c;大胆地去走自己的夜路 一、常见概念 在正式介绍分布式系…

16、OpenFeign和Sentinel集成实现fallback服务降级

注&#xff1a;本篇文章主要参考周阳老师讲解的cloud进行整理的&#xff01; 1、需求说明 cloudalibaba-consumer-nacos-order83 通过OpenFeign调用 cloudalibaba-provider-payment9001 1、 83 通过OpenFeign调用 9001微服务&#xff0c;正常访问OK 2、 83 通过OpenFeign调用 …

推特社交机器人分类

机器人有不同的种类。 cresci-17数据集中的三种不同的机器人类:传统垃圾机器人、社交垃圾机器人和假追随者。 传统的垃圾邮件机器人会生成大量推广产品的内容&#xff0c;并且可以通过频繁使用的形容词来检测; 社交垃圾邮件倾向于攻击或支持政治候选人&#xff0c;因此情绪是一…

centos配置natapp 自动配置

步骤 下载客户端 赋值权限 启动测试是否可用配置natapp.service 设置自动启动 natapp.service 配置的文件夹需要跟 natapp的路径一致 下载配置文件 centos 这里 我用的 natapp_autostart-master\natapp_autostart-master\systemd 文件夹下的 natapp.service 上传natapp到服…

深入解析大语言模型显存占用:训练与推理

深入解析大语言模型显存占用&#xff1a;训练与推理 文章脉络 估算模型保存大小 估算模型在训练时占用显存的大小 全量参数训练 PEFT训练 估算模型在推理时占用显存的大小 总结 对于NLP领域的从业者和研究人员来说&#xff0c;有没有遇到过这样一个场景&#xff0c;你的…

小白一次过软考高级(信息系统项目管理师)秘籍,请收藏!!!

作为一位软考老司机&#xff0c;我觉得我还是有资格说一说的。 我的考试成绩&#xff1a; 高级软考考试基础信息&#xff1a; 考试科目&#xff1a;总共分为3科&#xff0c;综合知识、案例分析、论文 成绩&#xff1a;满分75分&#xff0c;45分及格&#xff0c;需同时通过3科…

抽象类和接口(1)(抽象类部分)

❤️❤️前言 hellohello~&#xff0c;大家好&#x1f495;&#x1f495;&#xff0c;这里是E绵绵呀✋✋ &#xff0c;如果觉得这篇文章还不错的话还请点赞❤️❤️收藏&#x1f49e; &#x1f49e; 关注&#x1f4a5;&#x1f4a5;&#xff0c;如果发现这篇文章有问题的话&…

初步接触C++

hello&#xff0c;各位小伙伴&#xff0c;本篇文章跟大家一起学习C&#xff0c;感谢大家对我上一篇的支持&#xff0c;如有什么问题&#xff0c;还请多多指教 &#xff01; 文章目录 初步区别C语言和C命名空间1.命名空间的定义2.命名空间的使用 C的输入输出缺省参数1.缺省参数…

Python Flask-Mail实现邮件发送

一、邮件发送的扩展 关于如何找到flask发送邮件的插件&#xff1f;&#xff0c;上一篇已经分享了如何找到第三方插件&#xff0c;也找到了插件flask-mail的使用文档&#xff0c;那我们就来实战吧 二、根据文档&#xff0c;总结发送邮件的流程 从文档中可以总结出发送邮件的步…

【进程控制】谈谈进程终止的三种状态

文章目录 进程终止退出码信号信号术语 进程常见的退出方法exit函数与_exit函数的区别对比exit和_exit函数对于缓冲区的处理 进程终止 进程终止&#xff0c;也就是进程运行结束。结束有两种含义&#xff0c;一种是“正常”结束&#xff0c;带有结果&#xff0c;即代码运行完毕。…

第十三届蓝桥杯省赛C++ A组 Java A组/研究生组《推导部分和》(C++)

【题目描述】 【输入格式】 【输出格式】 【数据范围】 【输入样例】 5 3 3 1 5 15 4 5 9 2 3 5 1 5 1 3 1 2 【输出样例】 15 6 UNKNOWN 【思路】 题解来源&#xff1a;AcWing 4651. $\Huge\color{gold}{推导部分和}$ - AcWing 【代码】 #include<bits/stdc.h> #define…