1# 使用Node-API调用返回值为promise的ArkTS方法 2 3## 场景介绍 4当ArkTS的返回值为promise,开发者可以按照以下方式在自己创建的ArkTS运行环境中调用异步的ArkTS接口。 5 6## 调用异步的ArkTS接口示例 7从c++使用NAPI调用返回Promise的ArkTS方法。 8处理Promise对象:将Promise与c++回调绑定,处理异步结果。 9转换数据类型:在回调中将JavaScript结果转换为c++可用的数据。 10线程安全处理:确保跨线程操作的安全性。 11 12### 示例代码 13- 模块注册 14 ```c++ 15 #include "hilog/log.h" 16 #include "napi/native_api.h" 17 #include <napi/common.h> 18 #include <pthread.h> 19 20 //解析Promise结果的回调 21 static napi_value ResolvedCallback(napi_env env, napi_callback_info info) 22 { 23 size_t argc = 1; 24 napi_value args[1]; 25 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); 26 27 int result; 28 napi_get_value_int32(env, args[0], &result); 29 OH_LOG_INFO(LOG_APP, "Promise resolved with result:%{public}d", result); 30 return nullptr; 31 } 32 33 //拒绝Promise的回调 34 static napi_value RejectedCallback(napi_env env, napi_callback_info info) 35 { 36 size_t argc = 1; 37 napi_value args[1]; 38 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); 39 40 napi_value error; 41 napi_coerce_to_string(env, args[0], &error); 42 char errorMsg[1024]; 43 size_t len; 44 napi_get_value_string_utf8(env, error, errorMsg, sizeof(errorMsg), &len); 45 OH_LOG_ERROR(LOG_APP, "Promise rejected with error:%{public}s", errorMsg); 46 return nullptr; 47 } 48 49 static napi_value CallArkTSAsync(napi_env env, napi_callback_info info) 50 { 51 size_t argc = 1; 52 napi_value argv[1] = { nullptr }; 53 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); 54 napi_value promise = nullptr; 55 napi_call_function(env, nullptr, argv[0], 0, nullptr, &promise); 56 57 napi_value thenFunc = nullptr; 58 if (napi_get_named_property(env, promise, "then", &thenFunc) != napi_ok) { 59 return nullptr; 60 } 61 62 napi_value onResolve = nullptr; 63 napi_value onReject = nullptr; 64 napi_create_function(env, "onResolve", NAPI_AUTO_LENGTH, ResolvedCallback, nullptr, &onResolve); 65 napi_create_function(env, "onReject", NAPI_AUTO_LENGTH, RejectedCallback, nullptr, &onReject); 66 napi_value argv1[2] = {onResolve, onReject}; 67 napi_call_function(env, promise, thenFunc, 2, argv1, nullptr); 68 69 return nullptr; 70 } 71 72 // 注册模块接口 73 EXTERN_C_START 74 static napi_value Init(napi_env env, napi_value exports) 75 { 76 napi_property_descriptor desc[] = { 77 {"callArkTSAsync", nullptr, CallArkTSAsync, nullptr, nullptr, nullptr, napi_default, nullptr} 78 }; 79 napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); 80 return exports; 81 } 82 EXTERN_C_END 83 84 static napi_module nativeModule = { 85 .nm_version = 1, 86 .nm_flags = 0, 87 .nm_filename = nullptr, 88 .nm_register_func = Init, 89 .nm_modname = "entry", 90 .nm_priv = nullptr, 91 .reserved = { 0 }, 92 }; 93 94 extern "C" __attribute__((constructor)) void RegisterEntryModule() 95 { 96 napi_module_register(&nativeModule); 97 } 98 ``` 99 100- 接口声明 101 ```ts 102 // index.d.ts 103 export const callArkTSAsync: (func: Function) => object; 104 ``` 105 106- 编译配置 1071. CMakeLists.txt文件需要按照如下配置 108 ``` 109 // CMakeLists.txt 110 # the minimum version of CMake. 111 cmake_minimum_required(VERSION 3.4.1) 112 project(myapplication) 113 114 set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}) 115 116 if(DEFINED PACKAGE_FIND_FILE) 117 include(${PACKAGE_FIND_FILE}) 118 endif() 119 120 include_directories(${NATIVERENDER_ROOT_PATH} 121 ${NATIVERENDER_ROOT_PATH}/include) 122 add_library(entry SHARED hello.cpp) 123 target_link_libraries(entry PUBLIC libace_napi.z.so) 124 ``` 1252. 需要在工程的build-profile.json5文件中进行以下配置 126 ```json 127 { 128 "buildOption" : { 129 "arkOptions" : { 130 "runtimeOnly" : { 131 "sources": [ 132 "./src/main/ets/pages/ObjectUtils.ets" 133 ] 134 } 135 } 136 } 137 } 138 ``` 139- ArkTS代码示例 140 ```ts 141 // index.ets 142 import testNapi from 'libentry.so' 143 144 export function SetTimeout() : Promise<number> { 145 return new Promise((resolve) => { 146 setTimeout(() => { 147 resolve(42); 148 }, 1000) 149 }) 150 } 151 testNapi.callArkTSAsync(SetTimeout); 152 ``` 153