OpenHarmony实战开发-如何使用Node-API接口进行异步任务开发

567 篇文章 4 订阅
555 篇文章 0 订阅

场景介绍

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

  • 文件操作:读取大型文件或执行复杂的文件操作时,可以使用异步工作对象来避免阻塞主线程。
  • 网络请求:当需要进行网络请求并等待响应时,使用异步工作对象可以确保主线程不被阻塞,从而提高应用程序的响应性能。
  • 数据库操作:当需要执行复杂的数据库查询或写入操作时,使用异步工作对象可以确保主线程不被阻塞,从而提高应用程序的并发性能。
  • 图像处理:当需要对大型图像进行处理或执行复杂的图像算法时,使用异步工作对象可以确保主线程不被阻塞,从而提高应用程序的实时性能。

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

NAPI 异步任务线程

使用Promise方式示例
NAPI Promise异步流程

使用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;
}

2.定义异步任务的第一个回调函数,该函数在工作线程中执行,处理具体的业务逻辑。

static void ExecuteCB(napi_env env, void *data)
{
    CallbackData *callbackData = reinterpret_cast<CallbackData *>(data);
    callbackData->result = callbackData->args;
}

3.定义异步任务的第二个回调函数,该函数在主线程执行,将结果传递给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;
}

4.模块初始化以及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;
}

2.定义异步任务的第一个回调函数,该函数在工作线程中执行,处理具体的业务逻辑。

static void ExecuteCB(napi_env env, void *data) 
{
    CallbackData *callbackData = reinterpret_cast<CallbackData *>(data);
    callbackData->result = callbackData->args[0] + callbackData->args[1];
}

3.定义异步任务的第二个回调函数,该函数在主线程执行,将结果传递给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;
}

4.模块初始化以及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);
}); 

我这边特意整理了《鸿蒙语法ArkTS、TypeScript、ArkUI、实战开发视频教程》以及《鸿蒙生态应用开发白皮书V2.0PDF》《鸿蒙开发学习手册》(共计890页)鸿蒙开发资料等…希望对大家有所帮助:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

鸿蒙语法ArkTS、TypeScript、ArkUI等…视频教程:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

在这里插入图片描述

OpenHarmony APP开发教程步骤:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

在这里插入图片描述

鸿蒙生态应用开发白皮书V2.0PDF:https://docs.qq.com/doc/DZVVkRGRUd3pHSnFG

在这里插入图片描述

应用开发中级就业技术:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

在这里插入图片描述

应用开发中高级就业技术:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

在这里插入图片描述

南北双向高工技能基础:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

在这里插入图片描述

全网首发-工业级 南向设备开发就业技术:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

在这里插入图片描述

《鸿蒙开发学习手册》:

如何快速入门:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

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

在这里插入图片描述

开发基础知识:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

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

在这里插入图片描述

基于ArkTS 开发:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

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

在这里插入图片描述

  • 9
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值