【问题标题】:Async await in native module本机模块中的异步等待
【发布时间】:2019-11-17 03:01:07
【问题描述】:

我正在学习如何使用node-addon-api,现在我被困在异步/等待管理上。我无法理解如何处理本机函数接收具有异步函数的对象的情况。

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)

我的问题是我没有找到有关此行为的任何文档。我读到了如何在本机中创建一个 Promise,但没有从 JS 接收到如何使用它。

【问题讨论】:

  • 你想用承诺做什么?可能你会想调用它的then 方法,没有什么别的了。 (不,我怀疑 C++ 中有 await 对应)
  • 是的,我会使用在本机代码中具有异步方法的 JS 类。我不明白这种对象应该如何包装。
  • 你不会将它与返回承诺的普通方法不同。
  • C++ 20 中会出现 async/await,称为协程,可以作为很多编译器的实验特性使用。然后,围绕 Promise 创建自己的可等待包装器。
  • 等待某事等同于轮询标志或使用回调 - 在主线程中意味着暂停执行 - 因此您可以将其包装在 std::thread 或类似的返回一个 deferred:: promise() - 但现在我想知道什么信息如此重要以至于它必须在本机中调​​用并且之前不能在 js 中等待?

标签: node.js promise async-await node-addon-api


【解决方案1】:

在 C++ 插件方面,您必须异步实现功能并返回 Promise。请参阅下面的链接以获取确切的示例。

在 Javascript 方面,您必须将该 async/Promise 调用包装在显式异步 Javascript 函数中。否则,如果您尝试等待 Promise,您将收到有关该函数不是异步的错误。所以在你的 JS 方面,类似下面的东西应该可以工作:

async function init() {
  let obj = new YourAddon()
  let cnxnResult = await obj.connect()
}
init()

因此您可以创建自己的 Javascript 类(如您的代码示例)来包装此 C++ 功能并保持一切异步/等待友好。

我发现此链接对于展示 C++ 插件端的架构特别有用: Promise / AsyncWorker example

【讨论】:

    猜你喜欢
    • 2018-04-05
    • 2019-03-04
    • 1970-01-01
    • 2019-02-16
    • 1970-01-01
    • 2013-10-12
    • 2016-04-26
    • 1970-01-01
    • 2021-10-22
    相关资源
    最近更新 更多