我在文档和示例中找不到如何正确处理
Object/Buffer/Uint8Array
中的AsyncWorker
参数?
任务:我想接收数据作为
Uint8Array
并在 AsyncWorker
中使用它。
如果我理解正确的话,数据可以被垃圾收集。
我应该:
ObjectReference
中并将其传递给 AsyncWorker
构造函数?Uint8Array
包裹在 ObjectReference` 中?uint8_t* data
包裹起来?天真的代码:
#include "napi.h"
class DoHeavyMathWorker : public Napi::AsyncWorker {
public:
DoHeavyMathWorker(const Napi::Env& env, uint8_t* data)
: Napi::AsyncWorker{env, "DoHeavyMathWorker"},
m_deferred{env},
m_data{data}
{}
Napi::Promise GetPromise() { return m_deferred.Promise(); }
protected:
void Execute() {
// heavy math with data
if (m_data[0] == 0) {
m_result = 1;
} else {
m_result = 2;
}
}
void OnOK() { m_deferred.Resolve(Napi::Number::New(Env(), m_result)); }
void OnError(const Napi::Error& err) { m_deferred.Reject(err.Value()); }
private:
Napi::Promise::Deferred m_deferred;
uint8_t* m_data;
uint32_t m_result;
};
Napi::Value DoHeavyMath(const Napi::CallbackInfo& info) {
Napi::Env env = info.Env();
if (!info[0].IsObject()) {
Napi::TypeError::New(env, "arg must be an object")
.ThrowAsJavaScriptException();
return env.Undefined();
}
Napi::Object obj = info[0].As<Napi::Object>();
uint8_t* data = obj.Get("data").As<Napi::Uint8Array>().Data();
DoHeavyMathWorker* worker = new DoHeavyMathWorker(env, data);
worker->Queue();
return worker->GetPromise();
}
Napi::Object Init(Napi::Env env, Napi::Object exports) {
exports.Set("doHeavyMath", Napi::Function::New(env, DoHeavyMath));
return exports;
}
NODE_API_MODULE(NODE_GYP_MODULE_NAME, Init)
JS部分:
const result = await addon.doHeavyMath({
data: new Uint8Array([42]),
});
console.log('result:', result);
您必须创建一个持久引用,并在需要数据时保留它。请注意,持久引用只能在主线程上创建和销毁。
您应该在创建
AsyncWorker
的函数中的堆上创建它:
auto *persistent = new Napi::ObjectReference(
Napi::Persistent(array_buffer.As<Napi::Object>()));
将此引用传递给
AsyncWorker
并在 AsyncWorker
回调中将其删除 - OnOK
和 OnError
:
// This is everything needed to free the underlying reference
delete persistent;