调用napi_create_threadsafe_function创建ArkTS回调接口和线程安全回调函数,传入线程安全回调函数的ArkTS侧回调接口函数地址为0,无法正确获取到ArkTS侧回调函数的原始值。线程安全回调函数代码如下:

运行结果如下:

Node-API线程安全开发主要用于异步多线程之间共享和调用场景中使用,以避免出现竞争条件或死锁。例如以下场景:
napi_create_threadsafe_function:该接口主要用于创建线程安全对象,在创建的过程中,会注册异步过程中的关键信息:ArkTS回调接口callback和线程安全回调函数call_js_cb等。参数说明如下:
/**
* @brief 用于创建一个线程安全的函数,该函数可以在多个线程中调用,而不需要担心数据竞争或其他线程安全问题
*
* @param env 指向NAPI环境的指针,用于创建和操作Javascript值
* @param func 指向JavaScript函数的指针
* @param async_resource 异步资源,通常是一个表示异步操作的对象
* @param async_resource_name 指向资源名称的指针,这个名称将用于日志和调试
* @param max_queue_size 一个整数,表示队列的最大大小,当队列满时,新的调用将被丢弃
* @param initial_thread_count 无符号整数,表示在创建线程安全函数时,初始的线程数量
* @param thread_finalize_data 一个指向在所有线程之前需要清理的数据
* @param napi_finalize thread_finalize_cb 回调函数,当所有线程完成时被调用,用于清理资源
* @param context 指向上下文的指针,这个上下文将被传递给call_js_func函数
* @param call_js_cb 指向回调函数的指针,这个函数将在Javascript函数被调用时被调用
* @param result 指向napi_threadsafe_function结构的指针,这个结构将被填充为新创建的线程安全函数
*/
napi_status napi_create_threadsafe_function(napi_env env,
napi_value func,
napi_value async_resource,
napi_value async_resource_name,
size_t max_queue_size,
size_t initial_thread_count,
void* thread_finalize_data,
napi_finalize thread_finalize_cb,
void* context,
napi_threadsafe_function_call_js call_js_cb,
napi_threadsafe_function* result); ArkTS应用侧传入的回调接口参数传入到napi_create_threadsafe_function函数的第二个参数。通过线程安全回调函数CallJs执行,通过napi_call_function调用ArkTS回调接口,从而将异步计算结果反馈到ArkTS应用侧,用于应用侧UI刷新。示例代码如下:
static napi_value StartThread(napi_env env, napi_callback_info info)
{
size_t argc = 1;
napi_value jsCb = nullptr;
CallbackData *callbackData = new CallbackData(); // 异步任务完成时释放
napi_get_cb_info(env, info, &argc, &jsCb, nullptr, nullptr);
// 创建一个线程安全函数
napi_value resourceName = nullptr;
napi_create_string_utf8(env, "Thread-safe Function Demo", NAPI_AUTO_LENGTH, &resourceName);
napi_create_threadsafe_function(env, jsCb, nullptr, resourceName, 0, 1, nullptr, nullptr, nullptr, CallJs,
&callbackData->tsfn);
// 创建一个异步任务
// ExecuteWork会执行在一个由libuv创建的非JS线程上,此处使用napi_create_async_work是为了模拟在非JS线程场景使用napi_call_threadsafe_function接口向JS线程提交任务
napi_create_async_work(env, nullptr, resourceName, ExecuteWork, WorkComplete, callbackData, &callbackData->work);
// 将异步任务加入到异步队列中
napi_queue_async_work(env, callbackData->work);
return nullptr;
}