HarmonyOS 鸿蒙Next 使用Node-API接口进行线程安全开发,使用文档中的代码片段执行结果是无法完成回调。大佬能给一个完整demo吗?
HarmonyOS 鸿蒙Next 使用Node-API接口进行线程安全开发,使用文档中的代码片段执行结果是无法完成回调。大佬能给一个完整demo吗?
.cpp文件代码
```cpp
#include "napi/native_api.h"
#include <future>
struct CallbackData {
napi_threadsafe_function tsfn;
napi_async_work work;
};
static napi_value ResolvedCallback(napi_env env, napi_callback_info info) {
void *data = nullptr;
size_t argc = 1;
napi_value argv[1];
if (napi_get_cb_info(env, info, &argc, argv, nullptr, &data) != napi_ok) {
return nullptr;
}
size_t result = 0;
char buf[32] = {0};
napi_get_value_string_utf8(env, argv[0], buf, 32, &result);
reinterpret_cast<std::promise<std::string>*>(data)->set_value(std::string(buf));
return nullptr;
}
static napi_value RejectedCallback(napi_env env, napi_callback_info info) {
void *data = nullptr;
if (napi_get_cb_info(env, info, nullptr, nullptr, nullptr, &data) != napi_ok) {
return nullptr;
}
reinterpret_cast<std::promise<std::string>*>(data)->set_exception(
std::make_exception_ptr(std::runtime_error("Error in jsCallback")));
return nullptr;
}
static void CallJs(napi_env env, napi_value jsCb, void *context, void *data) {
if (env == nullptr) {
return;
}
napi_value undefined = nullptr;
napi_value promise = nullptr;
napi_get_undefined(env, &undefined);
napi_call_function(env, undefined, jsCb, 0, nullptr, &promise);
napi_value thenFunc = nullptr;
if (napi_get_named_property(env, promise, "then", &thenFunc) != napi_ok) {
return;
}
napi_value resolvedCallback;
napi_value rejectedCallback;
napi_create_function(env, "resolvedCallback", NAPI_AUTO_LENGTH, ResolvedCallback, data, &resolvedCallback);
napi_create_function(env, "rejectedCallback", NAPI_AUTO_LENGTH, RejectedCallback, data, &rejectedCallback);
napi_value argv[2] = {resolvedCallback, rejectedCallback};
napi_call_function(env, promise, thenFunc, 2, argv, nullptr);
}
static void WorkComplete(napi_env env, napi_status status, void *data) {
CallbackData *callbackData = reinterpret_cast<CallbackData*>(data);
napi_release_threadsafe_function(callbackData->tsfn, napi_tsfn_release);
napi_delete_async_work(env, callbackData->work);
callbackData->tsfn = nullptr;
callbackData->work = nullptr;
}
static void ExecuteWork(napi_env env, void *data) {
CallbackData *callbackData = reinterpret_cast<CallbackData*>(data);
std::promise<std::string> promise;
auto future = promise.get_future();
napi_call_threadsafe_function(callbackData->tsfn, &promise, napi_tsfn_nonblocking);
try {
auto result = future.get();
// OH_LOG_INFO(LOG_APP, "XXX, Result from JS %{public}s", result.c_str());
} catch (const std::exception &e) {
// OH_LOG_INFO(LOG_APP, "XXX, Result from JS %{public}s", e.what());
}
}
static napi_value StartThread(napi_env env, napi_callback_info info) {
size_t argc = 1;
napi_value jsCb = nullptr;
CallbackData *callbackData = nullptr;
napi_get_cb_info(env, info, &argc, &jsCb, nullptr, reinterpret_cast<void**>(&callbackData));
// 创建一个线程安全函数
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, callbackData, nullptr,
callbackData, CallJs, &callbackData->tsfn);
// 创建一个异步任务
napi_create_async_work(env, nullptr, resourceName, ExecuteWork, WorkComplete, callbackData,
&callbackData->work);
// 将异步任务加入到异步队列中
napi_queue_async_work(env, callbackData->work);
return nullptr;
}
EXTERN_C_START
// 模块初始化
static napi_value Init(napi_env env, napi_value exports) {
CallbackData *callbackData = new CallbackData(); // 可在线程退出时释放
napi_property_descriptor desc[] = {
{"startThread", nullptr, StartThread, nullptr, nullptr, nullptr, napi_default, callbackData},
};
napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
return exports;
}
EXTERN_C_END
// 模块基本信息
static napi_module demoModule = {
.nm_version = 1,
.nm_flags = 0,
.nm_filename = nullptr,
.nm_register_func = Init,
// import时填写的.so名称--lib****.so
.nm_modname = "entry",
.nm_priv = nullptr,
.reserved = {0},
};
// 加载so时,该函数会自动被调用,将上述demoModule模块注册到系统中。
extern "C" __attribute__((constructor))
void RegisterDemoModule() {
napi_module_register(&demoModule);
}
更多关于HarmonyOS 鸿蒙Next 使用Node-API接口进行线程安全开发,使用文档中的代码片段执行结果是无法完成回调。大佬能给一个完整demo吗?的实战教程也可以访问 https://www.itying.com/category-93-b0.html
3 回复
更多关于HarmonyOS 鸿蒙Next 使用Node-API接口进行线程安全开发,使用文档中的代码片段执行结果是无法完成回调。大佬能给一个完整demo吗?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS鸿蒙Next中使用Node-API进行线程安全开发时,确保回调函数正确执行需要注意几个关键点。以下是一个简单的示例,展示如何使用Node-API创建线程并执行回调:
#include <napi.h>
#include <thread>
#include <iostream>
void AsyncWork(napi_env env, void* data) {
// 模拟耗时操作
std::this_thread::sleep_for(std::chrono::seconds(2));
std::cout << "Async work completed" << std::endl;
}
void Callback(napi_env env, napi_status status, void* data) {
std::cout << "Callback executed" << std::endl;
}
Napi::Value StartAsyncWork(const Napi::CallbackInfo& info) {
Napi::Env env = info.Env();
napi_async_work work;
napi_create_async_work(env, nullptr, Napi::String::New(env, "AsyncWork"), AsyncWork, Callback, nullptr, &work);
napi_queue_async_work(env, work);
return Napi::Boolean::New(env, true);
}
Napi::Object Init(Napi::Env env, Napi::Object exports) {
exports.Set(Napi::String::New(env, "startAsyncWork"), Napi::Function::New(env, StartAsyncWork));
return exports;
}
NODE_API_MODULE(addon, Init)
在这个示例中,StartAsyncWork
函数创建了一个异步工作项napi_async_work
,并将其加入队列。AsyncWork
函数模拟了一个耗时操作,而Callback
函数则在工作完成后被调用。
确保以下几点:
napi_create_async_work
和napi_queue_async_work
正确使用。- 回调函数
Callback
在异步工作完成后被调用。 - 环境变量
env
在所有函数中正确传递。
此代码片段展示了如何在鸿蒙Next中使用Node-API进行线程安全开发,并确保回调函数正确执行。