通过事件发射调用JS函数

Calling a JS function by event emitting

本文关键字:JS 函数 调用 发射 事件      更新时间:2023-10-16

我不确定如何在Node的主线程中通过在单独的c++线程中使用事件发射来调用Node/v8函数。如何在c++线程中发出事件?

在考虑NanAsyncWorker或uv_queue_work之前:我不想以异步方式调用c++函数。我想做完全相反的事情,通过发出事件从c++调用Javascript函数。

您不需要使用uv_queue_work,但是LibUV的线程库的一部分是uv_async_*方法,这是您在这种情况下理想的。当您初始化二级线程时,您还可以执行uv_async_init来创建共享的async数据结构。当其他线程发送消息时,该函数也会与回调一起调用。这个回调就是你调用JS代码来触发事件的地方。

下面是一些半伪代码的例子:

在你的线程初始化函数从JS调用一个单一的回调参数:

void ThreadInit(const v8::Arguments &args){
  // This is just an example, this should be saved somewhere that
  // some_callback will be able to access it.
  v8::Persistent<v8::Function> js_callback = args[0].As<Function>();
  // And save this where you'll be able to call uv_close on it.
  uv_async_t async_data;
  uv_async_init(uv_default_loop(), &async_data, some_callback);
  // initialize the thread and pass it async_data
}
在线程:

async_data.data = (void*) // Some data structure...
uv_async_send(&async_data);

在线程回调中:

void some_callback(uv_async_t *async_data){
    // Note that this depending on the data, you could easily get thread-safety issues
    // here, so keep in mind that you should follow standard processes here.
    void* data = async_data->data;
    // Process that data however you need to in order to create a JS value, e.g.
    // Using NanNew because it is more readable than standard V8.
    v8::Local<Number> count = NanNew<Number>(data.count);
    v8::Local<v8::Value> argv[] = {
        count
    };
    js_callback->Call(NanNull(), 1, argv);
}