在 Promise 中包装本机 (c++) 方法
Wrap native (c++) method inside a Promise
我有一个执行繁重操作的同步 C++ Node.js 插件函数:
Napi::Object SyncHeavyFunction(const Napi::CallbackInfo& info) {
std::this_thread::sleep_for(std::chrono::seconds(50));
...
return env.Null();
}
我正在尝试 运行 将其异步包装成 javascript Promise:
console.log("before creating the Promise");
let p = new Promise((resolve) => {
const out = SyncHeavyFunction();
reolve(out)
});
console.log("after creating the Promise");
但是,Promise 的创建似乎会阻塞,直到底层本机函数终止。
我想知道这种行为是否是预期的,哪种是仅使用 javascript 代码实现同步本机函数的异步调用的最佳方式。
我最近转型了 gdal-next
(https://github.com/yocontra/node-gdal-next) to a completely asynchronous API (https://github.com/mmomtchev/node-gdal-async).
我可能会结束写教程,因为这是一个常见问题。
这远非微不足道,但基本上可以归结为为每个作业创建异步工作程序 (Napi::AsyncWorker
),然后在完成时调用 JS 回调。正是这个回调将解析 Promise
- 或者一旦你有一个带有回调的函数,你可以简单地使用 util.promisify
到 return a Promise
.
您还可以查看 https://github.com/nodejs/node-addon- api/blob/main/doc/async_worker.md 以获取准系统示例:
#include <napi.h>
#include <chrono>
#include <thread>
using namespace Napi;
class EchoWorker : public AsyncWorker {
public:
EchoWorker(Function& callback, std::string& echo)
: AsyncWorker(callback), echo(echo) {}
~EchoWorker() {}
// This code will be executed on the worker thread
void Execute() override {
// Need to simulate cpu heavy task
std::this_thread::sleep_for(std::chrono::seconds(1));
}
void OnOK() override {
HandleScope scope(Env());
Callback().Call({Env().Null(), String::New(Env(), echo)});
}
private:
std::string echo;
};
#include <napi.h>
// Include EchoWorker class
// ..
using namespace Napi;
Value Echo(const CallbackInfo& info) {
// You need to validate the arguments here.
Function cb = info[1].As<Function>();
std::string in = info[0].As<String>();
EchoWorker* wk = new EchoWorker(cb, in);
wk->Queue();
return info.Env().Undefined();
我有一个执行繁重操作的同步 C++ Node.js 插件函数:
Napi::Object SyncHeavyFunction(const Napi::CallbackInfo& info) {
std::this_thread::sleep_for(std::chrono::seconds(50));
...
return env.Null();
}
我正在尝试 运行 将其异步包装成 javascript Promise:
console.log("before creating the Promise");
let p = new Promise((resolve) => {
const out = SyncHeavyFunction();
reolve(out)
});
console.log("after creating the Promise");
但是,Promise 的创建似乎会阻塞,直到底层本机函数终止。 我想知道这种行为是否是预期的,哪种是仅使用 javascript 代码实现同步本机函数的异步调用的最佳方式。
我最近转型了 gdal-next
(https://github.com/yocontra/node-gdal-next) to a completely asynchronous API (https://github.com/mmomtchev/node-gdal-async).
我可能会结束写教程,因为这是一个常见问题。
这远非微不足道,但基本上可以归结为为每个作业创建异步工作程序 (Napi::AsyncWorker
),然后在完成时调用 JS 回调。正是这个回调将解析 Promise
- 或者一旦你有一个带有回调的函数,你可以简单地使用 util.promisify
到 return a Promise
.
您还可以查看 https://github.com/nodejs/node-addon- api/blob/main/doc/async_worker.md 以获取准系统示例:
#include <napi.h>
#include <chrono>
#include <thread>
using namespace Napi;
class EchoWorker : public AsyncWorker {
public:
EchoWorker(Function& callback, std::string& echo)
: AsyncWorker(callback), echo(echo) {}
~EchoWorker() {}
// This code will be executed on the worker thread
void Execute() override {
// Need to simulate cpu heavy task
std::this_thread::sleep_for(std::chrono::seconds(1));
}
void OnOK() override {
HandleScope scope(Env());
Callback().Call({Env().Null(), String::New(Env(), echo)});
}
private:
std::string echo;
};
#include <napi.h>
// Include EchoWorker class
// ..
using namespace Napi;
Value Echo(const CallbackInfo& info) {
// You need to validate the arguments here.
Function cb = info[1].As<Function>();
std::string in = info[0].As<String>();
EchoWorker* wk = new EchoWorker(cb, in);
wk->Queue();
return info.Env().Undefined();