Как разрешить Node.js Promise в N-Api Addon C
Моя основная проблема - вызвать асинхронную функцию из Node.js в аддоне и получить возвращаемое значение. Я пытаюсь выполнить обещание, возвращаемое вызываемой функцией JS.
index.js
const addon = require('./build/Debug/addon.node');
async function asunc_func() {
return "Hello asunc_func";
}
const result = addon.test_async(asunc_func); // addon returned a promise
result.then(res => {
console.log(res);
})
addon.cpp
#include <napi.h>
using namespace Napi;
int do_something_asynchronous(napi_deferred deferred, Napi::Function func, Napi::Env env) {
napi_value undefined;
napi_status status;
status = napi_get_undefined(env, &undefined);
if (status != napi_ok) return 0;
napi_value result = func.Call({});
// I want to get the string "Hello asunc_func" here
// from called JS function
napi_valuetype * result_type;
status = napi_typeof(env, result, result_type); // result_type: napi_object
if (result) {
status = napi_resolve_deferred(env, deferred, result);
} else {
status = napi_reject_deferred(env, deferred, undefined);
}
if (status != napi_ok) return 0;
deferred = NULL;
}
napi_value test_async(const Napi::CallbackInfo& info) {
Napi::Env env = info.Env();
Napi::Function func = info[0].As<Napi::Function>();
napi_deferred deferred;
napi_value promise;
napi_status status;
status = napi_create_promise(env, &deferred, &promise);
if (status != napi_ok) return NULL;
do_something_asynchronous(deferred, func, env);
return promise;
}
Napi::Object Init(Napi::Env env, Napi::Object exports) {
exports.Set(Napi::String::New(env, "test_async"), Napi::Function::New(env, test_async));
return exports;
}
NODE_API_MODULE(addon, Init)
В addon.cpp я хочу вызвать функцию async JS и получить возвращаемое значение
Я использовал этот документ в качестве примера https://nodejs.org/api/n-api.html
2 ответа
Ответ на следующий пост о переполнении стека также объясняет этот сценарий. В этом ответе разрешение / отклонение отложенного обещания выполняется в функции CompleteMyPromise1().
Как создать асинхронную функцию с помощью NAPI, возвращающую обещания
Вы должны сделать то же самое, как если бы вы делали это из JavaScript: вызвать
.then()
метод Promise и зарегистрировать обратный вызов.
Вот полный пример:
Napi::Value ret = asyncFunction.Call({});
if (!ret.IsPromise())
throw Napi::Error::New(env, "your function did not return a Promise");
Napi::Promise promise = ret.As<Napi::Promise>();
Napi::Value thenValue = promise.Get("then");
if (!thenValue.IsFunction())
throw Napi::Error::New(env, "Promise is not thenable");
Napi::Function then = thenValue.As<Napi::Function>();
Napi::Function callback = Napi::Function::New(env, Callback, "cpp_callback");
then.Call(promise, {callback});
The
Callback
функция получит данные из разрешенного промиса:
Napi::Value Callback(const Napi::CallbackInfo &info) {
printf("Callback called\n");
printf("Data: %s\n", info[0].ToString().Utf8Value().c_str());
return info.Env().Null();
}