如何在AsyncWorker中正确处理Object/Buffer/Uint8Array?

问题描述 投票:0回答:1

我在文档和示例中找不到如何正确处理

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);

c++ node.js node-gyp node.js-addon node-addon-api
1个回答
0
投票

您必须创建一个持久引用,并在需要数据时保留它。请注意,持久引用只能在主线程上创建和销毁。

您应该在创建

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;
© www.soinside.com 2019 - 2024. All rights reserved.