Async ждут в родном модуле
Я изучаю, как использовать node-addon-api, и теперь я застрял в управлении async/await. Я не могу понять, как обрабатывать случай, когда нативная функция получает объект, который имеет асинхронную функцию.
Javascript:
const addon = require('bindings')('addon');
class Foo {
async doAsync() {
...
}
}
const useFoo = () => {
const foo = new Foo();
await addon.doStuff(foo);
}
Родные:
#include <napi.h>
using namespace Napi;
Napi::Object doStuff(const Napi::CallbackInfo& info) {
Napi::Env env = info.Env();
MyObject* foo = Napi::ObjectWrap<MyObject>::Unwrap(info[0].As<Napi::Object>());
// How should I await for this?
foo.doAsync();
...
}
Napi::Object InitAll(Napi::Env env, Napi::Object exports) {
exports.Set(Napi::String::New(env, "doStuff"), Napi::Function::New(env, doStuff));
return exports;
}
NODE_API_MODULE(addon, InitAll)
Моя проблема в том, что я не нахожу никакой документации об этом поведении. Я читал о том, как создать обещание на нативном языке, но не о том, как его использовать при получении от JS.
0 ответов
На стороне надстройки C++ вы должны реализовать функциональность асинхронно и вернуть Promise. См. Ссылку ниже, чтобы увидеть именно это.
На стороне Javascript вы должны заключить этот вызов async/Promise в явно асинхронную функцию Javascript. В противном случае, если вы попытаетесь дождаться обещания, вы получите ошибку о том, что функция не является асинхронной. Итак, на вашей стороне JS должно работать что-то вроде следующего:
async function init() {
let obj = new YourAddon()
let cnxnResult = await obj.connect()
}
init()
Таким образом, вы можете создать свой собственный класс Javascript (например, примеры кода), чтобы обернуть эту функциональность C++ и сохранить все, что связано с async/await.
Я обнаружил, что эта ссылка особенно полезна для демонстрации того, как устроена сторона надстройки C++: пример Promise / AsyncWorker