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

Другие вопросы по тегам