Openharmony应用NAPI详解--进阶篇2
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相关推荐
- Openharmony应用NAPI详解--进阶篇1
NAPI面向C++的异步接口 3.C++实现NAPI异步接口需要做到三步 同步返回结果给js/ets调用者 另起线程完成异步操作 通过回调(callback)或Promise将异步操作结果返回 4.异 ...
- Openharmony应用NAPI详解--基础篇
NAPI是什么? 简单点理解就是在Openharmony里,实现上层js或ets应用与底层C/C++之间交互的框架. Openharmony里的官方解释:NAPI(Native API)组件是一套对外 ...
- Linux使用详解(进阶篇)
文章目录 Linux使用详解(进阶篇) 1.Linux目录说明 2.操作防火墙 3.ulimit命令和history命令 4.RPM和Yum的使用 5.设置系统字符集 6.vi & vim编辑 ...
- git 详解-进阶篇
git 从实践到生产力 承接上一篇 <git 入门篇>,详细讲解 git 命令具体应用. 提示:git 作为基础工具,代码开发 迭代维护非常适用. 文章目录 git 从实践到生产力 圈重点 ...
- mhdd应用详解-入门篇(图文教程)
mhdd应用详解-入门篇(图文教程) 来源:wxiu.com 作者:fox 时间:2009-03-13 点击: 54 对于专业的 电脑维修人员来说, MHDD是必备的硬盘工具,但是技术人员一般只拿他 ...
- IIS负载均衡-Application Request Route详解第一篇: ARR介绍
IIS负载均衡-Application Request Route详解第一篇: ARR介绍 说到负载均衡,相信大家已经不再陌生了,本系列主要介绍在IIS中可以采用的负载均衡的软件:微软的Appli ...
- IIS负载均衡-Application Request Route详解第二篇:创建与配置Server Farm
自从本系列发布之后,收到了很多的朋友的回复!非常感谢,同时很多朋友问到了一些问题,有些问题是一些比较基本的问题,由于时间的缘故,不会一一的为大家回复,如果有不明白的,希望大家勤自学!本系列虽然不难,但 ...
- IIS负载均衡-Application Request Route详解第二篇:创建与配置Server Farm(转载)
IIS负载均衡-Application Request Route详解第二篇:创建与配置Server Farm 自从本系列发布之后,收到了很多的朋友的回复!非常感谢,同时很多朋友问到了一些问题,有些问 ...
- bt协议详解 基础篇(上)
bt协议详解 基础篇(上) 最近开发了一个免费教程的网站,产生了仔细了解bt协议的想法,所以写了这一篇文章,后续还会写一些关于搜索和索引的东西,都是在开发这个网站的过程中学习到的技术,敬请期待. 1 ...
最新文章
- jq的ajax和模块引擎
- relocation R_X86_64_32S against `.data‘ can not be used when making a PIE object; recompile with -fP
- python-文件操作(1)
- C开源hash代码uthash的用法总结(2)
- 集合交集,并集,差集运算
- 分布式大型互联网企业架构
- 大数据第一季--Hadoop(day4)-徐培成-专题视频课程
- 鸿蒙 usb调试,刷机精灵如何打开usb调试模式
- Mac安装虚拟机详细步骤
- CMake Tutorial
- swift UI 学习 (一)
- 为什么程序员用笛卡尔心形曲线告白的人,都还是单身?
- 继续教育计算机考试试题,第四批继续教育计算机考试试题.doc
- java的数据类型:8大基本数据类型
- Java在编译到执行过程的编码问题
- 集团企业实验室信息化建设必经的之路
- java protected_java语言中protected是什么意思
- 探索Android 9.0 Pie新特性变更
- 计算机应用类专业综合知识试题
- Comprehensive survey of computational ECG analysis: Databases,methods and applications
热门文章
- Oracle并行服务器(OPS)12问
- 介孔二氧化硅纳米球 Mesoporous silica nanosphere 的介孔二氧化硅纳米球
- 基于vi构建强大的IDE
- Java生成条形码图片,并保存在指定路径
- 多年前的我,一如既往
- excel 数据透视表,笔记6,权亮
- Paper:可解释性之VI/PFI《All Models are Wrong, but Many are Useful: Learning a Variable’s Importance》翻译与解读
- 串口通信协议--UART、RS-232、RS-485、RS-422
- break语句和continue语句的区别
- 前端学习——HTML(一)