NAPI面向C++的异步接口(promise)

promise方式的处理方式

承接上文,与callback方式不同的是,promise对象由C++侧创建以返回值的方式传递回js/ets侧,promise对象存储异步执行的结果。

// foundation/filemanagement/file_api/interfaces/kits/js/src/common/napi/n_async/n_async_work_promise.cpp
NVal NAsyncWorkPromise::Schedule(string procedureName, NContextCBExec cbExec, NContextCBComplete cbComplete)
{ctx_->cbExec_ = move(cbExec);ctx_->cbComplete_ = move(cbComplete);napi_status status;napi_value result = nullptr;status = napi_create_promise(env_, &ctx_->deferred_, &result);if (status != napi_ok) {HILOGE("INNER BUG. Cannot create promise for %{public}d", status);return NVal();}napi_value resource = NVal::CreateUTF8String(env_, procedureName).val_;status = napi_create_async_work(env_, nullptr, resource, PromiseOnExec, PromiseOnComplete, ctx_, &ctx_->awork_);if (status != napi_ok) {HILOGE("INNER BUG. Failed to create async work for %{public}d", status);return NVal();}status = napi_queue_async_work(env_, ctx_->awork_);if (status != napi_ok) {HILOGE("INNER BUG. Failed to queue async work for %{public}d", status);return NVal();}ctx_ = nullptr; // The ownership of ctx_ has been transferedreturn { env_, result };
}

1.napi_create_promise创建创建Promise,返回promise、deferred 二个对象, promise用于主线程方法返回。 deferred对象用于resolve、reject处理。

首先先分析下napi_create_promise的方法定义

napi_status napi_create_promise(napi_env env,napi_deferred* deferred,napi_value* promise);

参数说明:

  • [in] env: 传入接口调用者的环境,包含js引擎等,由框架提供,默认情况下直接传入即可。

  • [out] deferred: 返回接收刚创建的deferred对象,关联Promise对象,后面用于napi_resolve_deferred() 或 napi_reject_deferred() 更新状态,返回数据。

  • [out] promise: 关联上面deferred对象的JS Promise对象,用于主线程方法返回。

返回值:返回napi_ok表示转换成功,其他值失败。

2.执行napi_create_async_work异步线程后,将deferred对象,通过napi_queue_async_work将创建的async work添加到队列,由NAPI框架的底层去调度后执行。

3.result即为返回的promise对象。

napi_create_async_work中的异步处理execute和complete方法,分别对应PromiseOnExec, PromiseOnComplete。处理完成后将ctx->res_结果更新至deferred的对象中。

static void PromiseOnExec(napi_env env, void *data)
{
...
}static void PromiseOnComplete(napi_env env, napi_status status, void *data)
{
...if (!ctx->res_.TypeIsError(true)) {napi_status status = napi_resolve_deferred(env, ctx->deferred_, ctx->res_.val_);if (status != napi_ok) {HILOGE("Internal BUG, cannot resolve promise for %{public}d", status);}} else {napi_status status = napi_reject_deferred(env, ctx->deferred_, ctx->res_.val_);if (status != napi_ok) {HILOGE("Internal BUG, cannot reject promise for %{public}d", status);}}ctx->deferred_ = nullptr;napi_delete_async_work(env, ctx->awork_);delete ctx;
}

最终返回临时结果NVal给js调用 (callback接口返回的是void, promise接口返回的是返回临时结果给js调用)。

此文讲解NAPI选用的分布式文件子系统,此实例将NAPI的接口封装成了多个操作的类(NAsyncWorkPromise、NAsyncWorkCallback、NVal等),对JS如何通过NAPI的调用C++调用流程与使用方式有一定的了解。如果想了解更多的NAPI的使用细节,可以在Openharmony的其它的子系统中查看其它的NAPI方法。以下提供NAPI的其它的一些接口说明和注意事项。

NAPI类型与接口说明

typedef enum {napi_undefined,napi_null,napi_boolean,napi_number,napi_string,napi_symbol,napi_object,napi_function,napi_external,napi_bigint
} napi_valuetype;
//对应了ECMAScript标准中定义的Undefined、Null、Boolean、Number、String、Symbol、Object、Function和BigInt九种数据类型。另外,napi_valuetype还包括了一个napi_external类型,其表示没有任何属性也没有任何原型的对象。napi_status napi_get_value_double(napi_env env,napi_value value,     // 获取的Javascript值double *result        // 用于保存对应的double类型值
);// napi_create_double创建其对应的Javascript double值result
napi_status napi_create_double(napi_env env,double value,         // double类型的值napi_value *result    // 保存创建的Javascript值
);// napi_create_string_utf8用于创建一个UTF-8类型的字符串对象,其值来自于参数传递的UTF-8编码字符串
napi_status napi_create_string_utf8(napi_env env,const char *str,size_t length,napi_value* result
);napi_status napi_get_value_double(napi_env env,napi_value value,     // 获取的Javascript值double *result        // 用于保存对应的double类型值
);// napi_create_double创建其对应的Javascript double值result
napi_status napi_create_double(napi_env env,double value,         // double类型的值napi_value *result    // 保存创建的Javascript值
);// napi_create_string_utf8用于创建一个UTF-8类型的字符串对象,其值来自于参数传递的UTF-8编码字符串
napi_status napi_create_string_utf8(napi_env env,const char *str,size_t length,napi_value* result
);// C/C++类型转NAPI类型
napi_status napi_create_object(napi_env env, napi_value *value);
napi_status napi_create_array(napi_env env, napi_value* value);//异步方法需要在不同线程中传递各种业务数据,定义一个结构体保存这些被传递的信息
struct MyAsyncContext {napi_env env = nullptr; // napi运行环境napi_async_work work = nullptr; // 异步工作对象napi_deferred deferred = nullptr; // 延迟执行对象(用于promise方式返回计算结果)napi_ref callbackRef = nullptr; // js callback function的引用对象 (用于callback方式返回计算结果)int32_t status;napi_value value[3];
};

其它一些API参考官方文档:

https://www.apiref.com/nodejs-zh/n-api.html

注意事项

1.回调函数callback字段使用napi_ref类型,不能使用napi_value类型。因napi_value类型对象生命周期在原生方法结束时结束,导致在work线程、EventLoop线程中获取不到,而napi_ref类型生命周期大于方法的。

2.NAPI在Openharmony的V3.2版本之后,添加了NAPI框架生成工具(napi_generator)子系统,故名思义,可以自动生成NAPI的框架,后续如果有读者对此有兴趣,可以专门开辟篇章进行说明。

后续更精彩

1.关于service ability的前世今生

2.L0设备在Openharmony基座上的开发实例

3.鸿蒙编译构建流程

Openharmony应用NAPI详解--进阶篇2相关推荐

  1. Openharmony应用NAPI详解--进阶篇1

    NAPI面向C++的异步接口 3.C++实现NAPI异步接口需要做到三步 同步返回结果给js/ets调用者 另起线程完成异步操作 通过回调(callback)或Promise将异步操作结果返回 4.异 ...

  2. Openharmony应用NAPI详解--基础篇

    NAPI是什么? 简单点理解就是在Openharmony里,实现上层js或ets应用与底层C/C++之间交互的框架. Openharmony里的官方解释:NAPI(Native API)组件是一套对外 ...

  3. Linux使用详解(进阶篇)

    文章目录 Linux使用详解(进阶篇) 1.Linux目录说明 2.操作防火墙 3.ulimit命令和history命令 4.RPM和Yum的使用 5.设置系统字符集 6.vi & vim编辑 ...

  4. git 详解-进阶篇

    git 从实践到生产力 承接上一篇 <git 入门篇>,详细讲解 git 命令具体应用. 提示:git 作为基础工具,代码开发 迭代维护非常适用. 文章目录 git 从实践到生产力 圈重点 ...

  5. mhdd应用详解-入门篇(图文教程)

    mhdd应用详解-入门篇(图文教程) 来源:wxiu.com 作者:fox 时间:2009-03-13 点击: 54 对于专业的 电脑维修人员来说, MHDD是必备的硬盘工具,但是技术人员一般只拿他 ...

  6. IIS负载均衡-Application Request Route详解第一篇: ARR介绍

    IIS负载均衡-Application Request Route详解第一篇: ARR介绍   说到负载均衡,相信大家已经不再陌生了,本系列主要介绍在IIS中可以采用的负载均衡的软件:微软的Appli ...

  7. IIS负载均衡-Application Request Route详解第二篇:创建与配置Server Farm

    自从本系列发布之后,收到了很多的朋友的回复!非常感谢,同时很多朋友问到了一些问题,有些问题是一些比较基本的问题,由于时间的缘故,不会一一的为大家回复,如果有不明白的,希望大家勤自学!本系列虽然不难,但 ...

  8. IIS负载均衡-Application Request Route详解第二篇:创建与配置Server Farm(转载)

    IIS负载均衡-Application Request Route详解第二篇:创建与配置Server Farm 自从本系列发布之后,收到了很多的朋友的回复!非常感谢,同时很多朋友问到了一些问题,有些问 ...

  9. bt协议详解 基础篇(上)

    bt协议详解 基础篇(上) 最近开发了一个免费教程的网站,产生了仔细了解bt协议的想法,所以写了这一篇文章,后续还会写一些关于搜索和索引的东西,都是在开发这个网站的过程中学习到的技术,敬请期待. 1 ...

最新文章

  1. jq的ajax和模块引擎
  2. relocation R_X86_64_32S against `.data‘ can not be used when making a PIE object; recompile with -fP
  3. python-文件操作(1)
  4. C开源hash代码uthash的用法总结(2)
  5. 集合交集,并集,差集运算
  6. 分布式大型互联网企业架构
  7. 大数据第一季--Hadoop(day4)-徐培成-专题视频课程
  8. 鸿蒙 usb调试,刷机精灵如何打开usb调试模式
  9. Mac安装虚拟机详细步骤
  10. CMake Tutorial
  11. swift UI 学习 (一)
  12. 为什么程序员用笛卡尔心形曲线告白的人,都还是单身?
  13. 继续教育计算机考试试题,第四批继续教育计算机考试试题.doc
  14. java的数据类型:8大基本数据类型
  15. Java在编译到执行过程的编码问题
  16. 集团企业实验室信息化建设必经的之路
  17. java protected_java语言中protected是什么意思
  18. 探索Android 9.0 Pie新特性变更
  19. 计算机应用类专业综合知识试题
  20. Comprehensive survey of computational ECG analysis: Databases,methods and applications

热门文章

  1. Oracle并行服务器(OPS)12问
  2. 介孔二氧化硅纳米球 Mesoporous silica nanosphere 的介孔二氧化硅纳米球
  3. 基于vi构建强大的IDE
  4. Java生成条形码图片,并保存在指定路径
  5. 多年前的我,一如既往
  6. excel 数据透视表,笔记6,权亮
  7. Paper:可解释性之VI/PFI《All Models are Wrong, but Many are Useful: Learning a Variable’s Importance》翻译与解读
  8. 串口通信协议--UART、RS-232、RS-485、RS-422
  9. break语句和continue语句的区别
  10. 前端学习——HTML(一)