nodejs使用libuv插件asynchronouscallback

我有一个节点js服务调用本地C库。 本土的图书馆,反复不断地发生火灾事件。 这些事件被传递给Ccallback函数。 我的目标是从这个本地Ccallback调用Javascriptcallback。

根据我的阅读,我使用uv_async_init和uv_async_send来实现这个目标。

我遇到的问题是我的本地Ccallback函数被调用了很多次,并且在那里uv_async_send被调用了很多次,但是传递给uv_async_init的函数只被调用了一次,只有当我的程序退出的时候。

这是我的C代码:

================================================== ===

#include "jsaudio.h" #include <iostream> using namespace v8; static void recordAudioCallback(int index); void asyncmsg(uv_async_t* handle); Callback* cbPeriodic; uv_async_t async; uv_loop_t* loop; NAN_METHOD(createEngine) { std::cout << "==> createEngine\n" ; } void createAudioRecorder(const Nan::FunctionCallbackInfo<v8::Value>& info) { std::cout << "==> createAudioRecorder\n"; } void startRecording(const Nan::FunctionCallbackInfo<v8::Value>& info) { std::cout << "==> startRecording\n"; cbPeriodic = new Callback(info[0].As<Function>()); loop = uv_default_loop(); uv_async_init(loop, &async, asyncmsg); } void asyncmsg(uv_async_t* handle) { std::cout << "==> asyncmsg \n"; Nan::HandleScope scope; v8::Isolate* isolate = v8::Isolate::GetCurrent(); Local<Value> argv[] = { v8::String::NewFromUtf8(isolate, "Hello world") }; cbPeriodic->Call(1, argv); } /* This my callback that gets called many times, by a native library*/ static void recordAudioCallback(int index) { std::cout << "==> recordAudioCallback " << index << "\n"; uv_async_send(&async); } 

================================================== ====

这是我的testingnode.js代码调用上述本机代码

 const jsAudio = new JsAudio({sampleRate: 48000, bufferSize: 8192}) function Test () { jsAudio.createEngine(); jsAudio.createAudioRecorder(); jsAudio.startRecording(function(error, result) { if (error) { console.log('startRecording failed: ' + error); } else { console.log('startRecording result: ' + result); } }); } Test(); var waitTill = new Date(new Date().getTime() + 3 * 1000); while(waitTill > new Date()){} jsAudio.shutdown(); console.log('program exit...'); 

================================================== ========

这里是:

 ==> createEngine ==> createAudioRecorder ==> startRecording ==> recordAudioCallback 0 ==> recordAudioCallback 1 ==> recordAudioCallback 0 ==> recordAudioCallback 1 ==> recordAudioCallback 0 ==> shutdown program exit... ==> asyncmsg startRecording failed: Hello world 

================================================== =========

为什么asyncmsg只被调用一次! 即使recordAudioCallback被多次调用! 任何为什么它被称为程序退出后!

任何帮助表示赞赏。

node.js中的Javascript代码的实际执行是单线程的。 这意味着callback不能在一些已经执行的JS代码中执行。

您的示例代码包含一个连续运行一段时间的繁忙循环,然后程序结束。 执行循环时,没有机会执行callback。

尝试使用setTimeout调用来replace该值,以按所需的间隔设置超时值。 像这样的东西:

 const jsAudio = new JsAudio({sampleRate: 48000, bufferSize: 8192}) function Test () { jsAudio.createEngine(); jsAudio.createAudioRecorder(); jsAudio.startRecording(function(error, result) { if (error) { console.log('startRecording failed: ' + error); } else { console.log('startRecording result: ' + result); } }); } Test(); setTimeout(function() { jsAudio.shutdown(); console.log('program exit...'); }, 3000); 

请注意,即使对setTimeout的调用将立即返回,您的程序不会退出。 这是因为node.js有一个事件循环,只要还有一些待处理的定时器或其他等待处理的事件就会继续。

有关事件循环的说明,请参阅node.js文档的这一部分 。