我有这样的代码:
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);
}
});
Run Code Online (Sandbox Code Playgroud)
我的问题是Node运行时会立即终止.它打印'Icanhasclient',但没有调用回调内的console.log.
(本例中的mysql是node-mysql.
有没有什么可以让node.js在退出之前等待回调完成?
geo*_*ert 47
回调未排队
节点一直运行,直到所有事件队列都为空.当调用诸如的调用时,会将回调添加到事件队列中
emmiter1.on('this_event',callback).
Run Code Online (Sandbox Code Playgroud)
已执行.此调用是模块开发人员编写的代码的一部分.
如果模块是来自同步/阻塞版本的快速端口,则可能不会发生这种情况,直到操作的某些部分完成并且所有队列在此之前可能为空,从而允许节点以静默方式退出.
这是一个偷偷摸摸的bug,也就是模块开发人员在开发过程中可能不会遇到的错误,因为在繁忙的系统中,它会在很多队列中发生,因为在关键时刻它们都很少是空的.
用户可能的修复/错误检测器是在可疑函数调用之前插入特殊的计时器事件.
小智 37
您可以使用setInterval发出setTimeout或重复超时.
如果要检查退出条件,还可以执行条件超时:
(function wait () {
if (!SOME_EXIT_CONDITION) setTimeout(wait, 1000);
})();
Run Code Online (Sandbox Code Playgroud)
把它放在你的代码的末尾,控制台就会等待......等待...直到你想让它关闭.
you*_*786 11
我的解决方案是实例化一个EventEmitter,并监听我的自定义事件.
var eventEmitter = new process.EventEmitter();
Run Code Online (Sandbox Code Playgroud)
然后我eventEmitter.emit从异步回调中调用:
client.connect(function (err) {
eventEmitter.emit('myevent', {something: "Bla"})
});
Run Code Online (Sandbox Code Playgroud)
我脚本中的最后一件事是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));
});
Run Code Online (Sandbox Code Playgroud)
然后节点将等待,直到事件处理程序完成运行.
根据@Todd 的回答,我创建了一个单线。将其包含在脚本的开头,并done = true在完成后设置:
var done = (function wait () { if (!done) setTimeout(wait, 1000) })();
Run Code Online (Sandbox Code Playgroud)
例子:
var done = (function wait () { if (!done) setTimeout(wait, 1000) })();
someAsyncOperation().then(() => {
console.log('Good to go!');
done = true;
});
Run Code Online (Sandbox Code Playgroud)
它是如何工作的?如果我们稍微扩展一下:
// Initialize the variable `done` to `undefined`
// Create the function wait, which is available inside itself
// Note: `var` is hoisted but `let` is not so we need to use `var`
var done = (function wait () {
// As long as it's nor marked as done, create a new event+queue
if (!done) setTimeout(wait, 1000);
// No return value; done will resolve to false (undefined)
})();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
50493 次 |
| 最近记录: |