Node.js N-API 插件 - 如何字符串化/解析 JSON?

Aar*_*rke 5 node.js node.js-addon node.js-napi

我正在使用N-API(C 接口,不要与围绕 N-API的node-addon-api C++ 包装器混淆)为 Node.js 编写一个插件,它从外部源接收 JSON 格式的数据并且需要在其对象形式上执行 JS 回调函数。但是,在将 JSON 格式的数据传递到 JS 回调之前,我无法将其解析为插件内的正确对象(即,由 JSON.parse 生成),并且似乎只能在其文本中传递它形式。

到目前为止,我发现的唯一示例涉及直接使用C++ NAN和 V8 API。我错过了什么吗?我应该对 JSON.parse 进行另一个 napi_call_function 调用,捕获它的返回值,然后传递它吗?(如果是这样,我如何从我的插件中获取 JSON.parse 回调信息?)有没有我没有找到的更简单的 API?

出于多种原因,我更愿意使用 C,而不是 C++,尽管我认为这是可以协商的。

foo.js

const myaddon = require('bindings')('myaddon');
const EventEmitter = require('events').EventEmitter;
const emitter = new EventEmitter();

emitter.on('eventReceived', (foo) => {
    var obj = JSON.parse(foo); // *** this is what I'd like to avoid ***
    console.log(obj.bar);
})

myaddon.RegisterForEvents(emitter.emit.bind(emitter));
Run Code Online (Sandbox Code Playgroud)

我的插件

void AsyncComplete(napi_env env, napi_status status, void * data) {

    // do some work to get the JSON text from the external source,
    // setup argv with the necessary values:
    // argv[0]: "eventReceived"
    // argv[1]: JSON text -- would like to deserialize in addon, not in JS callback, so the JS callback receives a proper object

    // Execute the JS function
    napi_call_function(env, global /* from napi_get_global */, callback /* the emitter */, argc, argv, NULL);
    // ...
Run Code Online (Sandbox Code Playgroud)

Vpa*_*ino 5

下面是如何在 C++ 端(而不是 Javascript 端)进行字符串化和解析的示例。Napi 允许您从 C++ 代码调用 javascript 函数。JSON.stringify()以下是如何调用&的示例JSON.parse()

Napi::String JSONStringify(const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();
  Napi::Object json_object = info[0].As<Napi::Object>();
  Napi::Object json = env.Global().Get("JSON").As<Napi::Object>();
  Napi::Function stringify = json.Get("stringify").As<Napi::Function>();
  return stringify.Call(json, { json_object }).As<Napi::String>();
}

Napi::Object JSONParse(const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();
  Napi::String json_string = info[0].As<Napi::String>();
  Napi::Object json = env.Global().Get("JSON").As<Napi::Object>();
  Napi::Function parse = json.Get("parse").As<Napi::Function>();
  return parse.Call(json, { json_string }).As<Napi::Object>();
}

Napi::Object Init(Napi::Env env, Napi::Object exports) {
  exports["jsonStringify"] =  Napi::Function::New(env, JSONStringify);
  exports["jsonParse"] = Napi::Function::New(env, JSONParse);          
  return exports;
}

NODE_API_MODULE(json, Init)
Run Code Online (Sandbox Code Playgroud)

来源:https ://github.com/nodejs/node-addon-api/issues/410#issuecomment-574876170