如何防止Node.js退出等待callback?

我有这样的代码:

var client = new mysql.Client(options); console.log('Icanhasclient'); client.connect(function (err) { console.log('jannn'); active_db = client; console.log(err); console.log('hest'); if (callback) { if (err) { callback(err, null); } callback(null, active_db); } }); 

我的问题是,当我运行它时,节点立即终止。 它打印“Icanhasclient”,但是没有任何console.log在callback中被调用。

(这个例子中的mysql是node-mysql 。

有没有什么可以做的,使node.js退出之前等待callback完成?

callback未被排队

节点运行,直到所有的事件队列都是空的。 一个callback被添加到一个事件队列当一个电话,如

  emmiter1.on('this_event',callback). 

已执行。 这个调用是模块开发人员编写的代码的一部分。

如果某个模块是来自同步/阻止版本的快速端口,则可能不会发生该操作的某些部分已经完成,并且所有队列都可能在此之前为空,从而允许节点以静默方式退出。

这是一个鬼鬼祟祟的错误,这是模块开发人员在开发过程中可能没有遇到的错误,因为在有很多队列的繁忙系统中,这种错误发生的频率较低,因为在关键时刻所有这些错误都是空的。

用户可能的修复/错误检测器是在可疑函数调用之前插入一个特殊的计时器事件。

你可以用setInterval发出一个setTimeout或定期的超时。

如果你想检查退出条件,你也可以做一个有条件的超时:

 (function wait () { if (!SOME_EXIT_CONDITION) setTimeout(wait, 1000); })(); 

把它放在你的代码的末尾,控制台就会等待…并等待…直到你想closures它。

我的解决scheme是实例化一个EventEmitter,并听我的自定义事件。

 var eventEmitter = new process.EventEmitter(); 

然后我从asynchronouscallback调用eventEmitter.emit

 client.connect(function (err) { eventEmitter.emit('myevent', {something: "Bla"}) }); 

我脚本中的最后一件事是eventEmitter.on

 eventEmitter.on('myevent', function(myResult){ // I needed the result to be written to stdout so that the calling process could get it process.stdout.write(JSON.stringify(myResult)); }); 

节点将等待,直到事件处理程序完成运行。

我看过felixge / node-mysql库,并没有在API中看到对命令client.connect的引用。 这是你试图做的实际的呼叫(不要试图在这里挑剔)? 无论如何,恕我直言,你需要更多地考虑Javascript是如何devise的,因为它使用与大多数其他stream行语言不同的编程范例。

我在你的代码中看到的第一个问题是你没有定义callback,所以它实际上并不存在。 我会假设console.log(callback)是未定义的。 从你的代码中,匿名函数是client.connect函数的“callback函数”。 你必须在更高的范围内定义你所说的“callback”。 例如,我将定义一个函数myCallback存在于比client.connect的匿名函数高的范围内。 查找Javacscript variables作用域可能很有用。

  var myCallback(err, response) { if (err) { console.log('err:%s',err); } else { console.log('response:%s',response); } } client.connect(err, function(response) { // this anonymous function is the callback to client.connect, the var // 'callback' would be undefined. if (err) { myCallback(err); return; // Explicit call to return, else the lines below would run. } myCallback(null, response); }); 

其次,如果你没有在Javascript中显式地调用return,那么这个函数将继续处理。 我被这个自己咬了。 最后,Javascript运行一个事件驱动的循环,这意味着它永远不会等待函数返回一个值,这就是为什么我们将所有这些callback放在首位。 您可以强制Javascript行为有所不同,例如通过使用while循环,直到条件为真。 请参阅caolan的“asynchronous”库,了解操作事件循环的各种策略。 过度使用这些方法的主要缺点是您实际上可能会浪费CPU周期/阻塞,因为您可能应该使用更多的callback,而只是重新考虑程序的工作方式。