Ausgabe
Für den Kontext habe ich mit dieser Frage begonnen. Ich muss den Rückruf für den Emitter in einem anderen Thread aufrufen. Ich habe ein Minimalbeispiel gemacht, aber es schlägt fehl. emit.Call({cb, result});
Mein erster Instinkt ist, dass ich ein Problem mit der Lebensdauer env
oder der emit
Funktion habe.
addon.cpp
#include <napi.h>
#include <iostream>
#include <thread>
#include <memory>
#include <functional>
#include <chrono>
std::shared_ptr<std::thread> thread;
bool running = true;
void generate(Napi::Env& env, Napi::Function& emit)
{
while(running)
{
Napi::Array result = Napi::Array::New(env);
for(int i = 0; i < 3; ++i)
{
result[i] = rand()%100;
}
auto cb = Napi::String::New(env, "onFeedData");
emit.Call({cb, result});
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
Napi::Value Start(const Napi::CallbackInfo& info)
{
Napi::Env env = info.Env();
Napi::Function emit = info[0].As<Napi::Function>();
auto cb = std::bind(generate, env, emit);
thread = std::make_shared<std::thread>(cb);
return Napi::String::New(env, "OK");
}
Napi::Value Stop(const Napi::CallbackInfo& info)
{
Napi::Env env = info.Env();
Napi::Function emit = info[0].As<Napi::Function>();
running = false;
thread->join();
return Napi::String::New(env, "OK");
}
Napi::Object Init(Napi::Env env, Napi::Object exports)
{
exports.Set(
Napi::String::New(env, "Start"),
Napi::Function::New(env, Start));
exports.Set(Napi::String::New(env, "Stop"),
Napi::Function::New(env, Stop));
return exports;
}
NODE_API_MODULE(addon, Init)
index.js
'use strict'
const EventEmitter = require('events').EventEmitter;
const addon = require('./build/addon.node');
function Main() {
const emitter = new EventEmitter();
emitter.on('onFeedData', (evt) => {
console.log(evt);
})
setTimeout(() => {
addon.Stop( emitter.emit.bind(emitter) );
}, 5000);
addon.Start( emitter.emit.bind(emitter) );
}
Main();
Lösung
Wir können dies erreichen, indem wir die Funktion napi_create_threadsafe_function () verwenden; Eine solche Verwendung wird ausführlich im StackOverflow-Posting How to use napi_threadsafe_function for NodeJS Native Addon erläutert
Hier ist die node.js-Dokumentation für asynchrone Thread-sichere Funktionsaufrufe
Beantwortet von – Satyan
Antwort geprüft von – Marilyn (FixError Volunteer)