Node.js でよく使用するパッケージはイベントです. このパッケージの下の EventEmitter が多くの場所で使用されていることがわかります. このイベントメカニズムに基づいて, 適切な新しい番号が到着したときに適切なことができます.
このメカニズムは、ネットワーク IO、ファイルの読み取りと書き込み、非同期タスクなどのシナリオに非常に適しています。
たとえば、次のコード
const events = require('events');
events.captureRejections = true;
const ee1 = new events.EventEmitter();
ee1.on('something', async (value) => {
throw new Error('kaboom');
});
ee1.on('error', console.log);
C++ プラグインは EventEmitter を使用します
EventEmitter.emit メソッドをプラグインに公開することで、プラグインに js コールバックを実装することができます。
addon.node にコンパイルするプラグインのコンパイルについては、前回の記事に詳しい方法があります。
#include <napi.h>
#include <chrono>
#include <iostream>
#include <thread>
Napi::Value CallEmit(const Napi::CallbackInfo& info) {
Napi::Env env = info.Env();
Napi::Function emit = info[0].As<Napi::Function>();
emit.Call({Napi::String::New(env, "start")});
for (int i = 0; i < 5; i++) {
std::this_thread::sleep_for(std::chrono::seconds(1));
emit.Call(
{Napi::String::New(env, "data"), Napi::String::New(env, "data ...")});
}
emit.Call({Napi::String::New(env, "end")});
return Napi::String::New(env, "OK");
}
// Init
Napi::Object Init(Napi::Env env, Napi::Object exports) {
exports.Set(Napi::String::New(env, "callEmit"),
Napi::Function::New(env, CallEmit));
return exports;
}
NODE_API_MODULE(NODE_GYP_MODULE_NAME, Init);
js呼び出しコード
const EventEmitter = require('events').EventEmitter
const addon = require('bindings')('addon.node')
const emitter = new EventEmitter()
emitter.on('start', () => {
console.log('### START ...')
})
emitter.on('data', (evt) => {
console.log(evt);
})
emitter.on('end', () => {
console.log('### END ###')
})
addon.callEmit(emitter.emit.bind(emitter))
出力は次のとおりです。