想了解更多内容,码解请访问: 和华为官方合作共建的码解鸿蒙技术社区 https://harmonyos.51cto.com JS API: JavaScript Application Programming Interface, JavaScript应用程序编程接口。 OpenHarmony上JS API实现方式有三种,码解分别是码解:JSI机制、Channel机制、码解NAPI机制。码解 JSI机制:L0~L1设备支持。码解 Channel机制:L3设备支持。码解 NAPI机制:目前仅L2设备支持,码解后续须推广到L3~L5设备。码解 一句话概括NAPI,码解就是码解L2设备上的 JS API实现方式。 优先封装异步方法!同步方法可待社区反馈需要时再行添加。码解 若引擎开启Promise特性支持,码解则异步方法必须同时支持Callback方式和Promise方式。码解使用哪种方式由应用开发者决定,以是否传递Callback进行区分。不传递Callback即为Promise方式,方法执行结果为Promise实例对象。 Promise 异步模型是 OHOS 标准异步模型之一。 Promise对象: ES6原生提供了Promise对象,Promise是异步编程的亿华云计算一种解决方案,可以替代传统的解决方案–回调函数和事件。promise对象是一个异步操作的结果,提供了一些API使得异步执行可以按照同步的流表示出来,避免了层层嵌套的回调函数,保证了回调是以异步的方式进行调用的。用户在调用这些接口的时候,接口实现将异步执行任务,同时返回一个 Promise 对象,其代表异步操作的结果。在返回的结果的个数超过一个时,其以对象属性的形式返回。 Promise特点 作为对象,Promise有两个特点:(1)对象的状态不受外界影响;(2)一旦状态改变了就不会再变,也就是说任何时候Promise都只有一种状态。 Callback 异步模型是 OHOS 标准异步模型之一。用户在调用这些接口的时候,接口实现将异步执行任务。服务器托管任务执行结果以参数的形式提供给用户注册的回调函数。这些参数的第一个是 Error 或 undefined 类型,分别表示执行出错与正常。 API集合按业务功能进行模块划分。开发者使用前须import对应的模块。 命名:@ohos.模块名 注意: N-API通过注册函数进行模块的注册,其接受一个全局变量参数,全局变量结构体中定义了模块名及模块初始化函数。在模块的初始化中,我们可以定义模块需要暴露的方法及属性。 示例: 模块定义 模块注册 声明文件模板 @ohos.模块名.d.ts文件: 示例: 声明文件@ohos.storage.d.ts JS API 调用流程如下图所示: 同步方法调用之后,将阻塞住JS线程直至获取到返回值。 命名:动词+Sync或动词+名词+Sync 格式: 返回值 声明文件模板 示例 声明 实现 异步方法调用整个过程不会阻碍调用者的工作。 命名:动词或动词+名词 格式: 返回值 声明文件模板 示例: 声明 实现 异步回调流程如下图所示: JS应用引用NAPI接口时,须先引用接口定义的对应模块,才能进行接口的调用。 想了解更多内容,请访问: 和华为官方合作共建的鸿蒙技术社区 https://harmonyos.51cto.com1.NAPI概念
1.1 JS API概念
1.2 JS API实现方式
1.3 NAPI概念
2.NAPI机制介绍
2.1 实现原则
2.2 异步编程模型
2.2.1Promise 异步模型
2.2.2Callback 异步模型
2.2 实现步骤
2.2.1 模块注册
2.2.2 NAPI声明
2.2.2 NAPI实现
接口定义
/**入参** napi_env:表示一个上下文的变量; napi_callback_info:传递给回调函数的一个封装的数据类型,可以用于获取有关调用时的上下文信息,也可以用于设置回调函数的返回值; **返回值** napi_value:对所有js的基本值的一个密闭封装,就是表示一个基本值; */ static napi_value Get(napi_env env, napi_callback_info info); static napi_value GetSync(napi_env env, napi_callback_info info); 2.2.2.1 同步回调
2.2.2.2 异步回调
static napi_value Get(napi_env env, napi_callback_info info) { size_t requireArgc = 1; size_t argc = 3; //参数个数 napi_value argv[3] = { 0 }; //参数定义 napi_value thisVar = nullptr; //JS对象的this参数 void* data = nullptr; //回调数据指针 /* 根据环境变量获取参数 */ napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); NAPI_ASSERT(env, argc >= requireArgc, "requires 1 parameter"); /* 异步接口上下文,用于接收JS接口传进来的环境变量、参数、回调函数、接口返回值等*/ auto asyncContext = new StorageAsyncContext(); asyncContext->env = env; for (size_t i = 0; i < argc; i++) { napi_valuetype valueType = napi_undefined; napi_typeof(env, argv[i], &valueType); if ((i == 0) && (valueType == napi_string)) { /* 根据JS字符串获取对应的UTF8编码格式的C/C++字符串 */ napi_get_value_string_utf8(env, argv[i], asyncContext->key, KEY_BUFFER_SIZE, &asyncContext->keyLen); } else if (valueType == napi_string) { napi_get_value_string_utf8(env, argv[i], asyncContext->value, VALUE_BUFFER_SIZE, &asyncContext->valueLen); } else if (valueType == napi_function) { /* 根据JS对象参数argv[i]新建引用 */ napi_create_reference(env, argv[i], 1, &asyncContext->callbackRef); break; } else { NAPI_ASSERT(env, false, "type mismatch"); } } napi_value result = nullptr; if (asyncContext->callbackRef == nullptr) { /* Promise方式异步调用,创建延迟对象、JS Promise对象,使二者进行关联 */ napi_create_promise(env, &asyncContext->deferred, &result); } else { /* Callback方式异步调用,不需要返回Promise对象,返回一个JS未定义值 */ napi_get_undefined(env, &result); } /* 根据JS对象获取与之绑定的原生对象实例 */ napi_unwrap(env, thisVar, (void**)&asyncContext->objectInfo); napi_value resource = nullptr; napi_create_string_utf8(env, "JSStorageGet", NAPI_AUTO_LENGTH, &resource); //获取JS异步资源名称 /* 创建异步工作 */ napi_create_async_work( env, nullptr, resource, /* 执行异步逻辑的原生函数 */ [](napi_env env, void* data) { StorageAsyncContext* asyncContext = (StorageAsyncContext*)data; auto itr = g_keyValueStorage.find(asyncContext->key); if (itr != g_keyValueStorage.end()) { if (strncpy_s(asyncContext->value, VALUE_BUFFER_SIZE, itr->second.c_str(), itr->second.length()) == -1) { asyncContext->status = 1; //失败 } else { asyncContext->status = 0; //成功 } } else { asyncContext->status = 1; //失败 } }, /* 异步函数执行完成或者取消后,需要执行的后处理函数 */ [](napi_env env, napi_status status, void* data) { StorageAsyncContext* asyncContext = (StorageAsyncContext*)data; napi_value result[2] = { 0 }; if (!asyncContext->status) { napi_get_undefined(env, &result[0]); napi_create_string_utf8(env, asyncContext->value, strlen(asyncContext->value), &result[1]); } else { napi_value message = nullptr; napi_create_string_utf8(env, "key does not exist", NAPI_AUTO_LENGTH, &message); napi_create_error(env, nullptr, message, &result[0]); napi_get_undefined(env, &result[1]); asyncContext->objectInfo->Emit(nullptr, "error"); } if (asyncContext->deferred) { if (!asyncContext->status) { /* 异步函数执行成功后,执行成功后处理函数 */ napi_resolve_deferred(env, asyncContext->deferred, result[1]); } else { /* 异步函数执行失败后,执行失败后处理函数 */ napi_reject_deferred(env, asyncContext->deferred, result[0]); } } else { napi_value callback = nullptr; napi_get_reference_value(env, asyncContext->callbackRef, &callback); napi_call_function(env, nullptr, callback, sizeof(result) / sizeof(result[0]), result, nullptr); napi_delete_reference(env, asyncContext->callbackRef); } /* 异步回调完成后进行资源释放 */ napi_delete_async_work(env, asyncContext->work); delete asyncContext; }, /* 用户数据上下文,此数据传递给异步执行函数与后处理函数 */ (void*)asyncContext, /* 生成的异步工作*/ &asyncContext->work); napi_queue_async_work(env, asyncContext->work); //异步工作入队列,排队执行 return result; }
3. 应用代码示例