Wrapped Napi-extracted functions into C++ `shared_ptr<>`-s for easier lifetime management.
Hi @gengjiawen,
Was hoping for some feedback -- after experimenting with node-addon-api for a few days looks like I've managed to wrap the extracted functions into C++ objects that do not require explicit lifetime management. Would be grateful for your time, and about as grateful if you could point me to someone else who would be better suited and/or would have more time.
A one-liner to run the code:
git clone -b cpp_thread_safe_calls https://github.com/dkorolev/node-addon-examples && (cd node-addon-examples/thread_safe_function_counting_wrapped/node-addon-api; npm i && node addon.js)
Results in:
RunAsyncWork(): calling the C++ function.
RunAsyncWork(): the promise is returned from C++.
Callback from C++: odd one=1.
Callback from C++: even two=2.
Callback from C++: odd three=3.
Callback from C++: even four=4.
Callback from C++: odd five=5.
RunAsyncWork(): the promise resolved, from C++, to true.
The relevant JavaScript piece:
const { runAsyncWork } = require('bindings')('addon');
console.log('RunAsyncWork(): calling the C++ function.');
const promise = runAsyncWork(
(i, s) => { console.log(`Callback from C++: even ${s}=${i}.`); },
(i, s) => { console.log(`Callback from C++: odd ${s}=${i}.`); }
);
console.log('RunAsyncWork(): the promise is returned from C++.');
promise.then((value) => { console.log(`RunAsyncWork(): the promise resolved, from C++, to ${value}.`); });
And the respective C++ one (the real code has comments, just pasting the cleaned up version here):
Napi::Value RunAsyncWork(const Napi::CallbackInfo& cbinfo) {
NodeJSContext ctx(cbinfo);
NodeJSFunction f_even = ctx.ExtractJSFunction(cbinfo[0]);
NodeJSFunction f_odd = ctx.ExtractJSFunction(cbinfo[1]);
ctx.RunAsync([f_even, f_odd]() {
struct IntString final { int i; std::string s; };
for (IntString& value : std::vector<IntString>({{1, "one"}, {2, "two"}, {3, "three"}, {4, "four"}, {5 ,"five"}})) {
((value.i % 2 == 0) ? f_even : f_odd)(value.i, value.s);
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
});
return ctx.GetPromise();
}
@KevinEady, @gabrielschulhof would probably make sense for one or both of you to take a look at this one.
@KevinEady, @gabrielschulhof ping
@KevinEady wondering what the next step on this is?