A package we often use in Node.js is events. We can see that the EventEmitter under this package is used in many places. Based on this event mechanism, we can do appropriate things when the appropriate new number arrives.
This mechanism is very suitable for scenarios such as network IO, file reading and writing, and asynchronous tasks.
For example the following code
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++ plugin uses EventEmmitter
By exposing the EventEmitter.emit method to the plug-in, js callback can be implemented in the plug-in. The following code we assume
Compile it into addon.node. As for compiling the plugin, I have a detailed method in the previous article.
#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 calling code
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))
The output is as follows