Node.js:在退出之前,节点是否总是等待setTimeout()完成?

考虑:

node -e "setTimeout(function() {console.log('abc'); }, 2000);" 

在程序退出之前,这实际上会等待超时。

我基本上想知道这是否意味着这个节点打算在退出之前等待所有超时完成。

这是我的情况。 我的客户端有一个node.js服务器,他将从Windows上运行一个快捷方式图标。 如果节点应用程序遇到exception情况,它通常会立即退出,没有足够的时间在控制台中看到错误是什么,这是不好的。

我的方法是用try catch包装整个程序,所以现在看起来像这样: try { (function () { ... })(); } catch (e) { console.log("EXCEPTION CAUGHT:", e); } try { (function () { ... })(); } catch (e) { console.log("EXCEPTION CAUGHT:", e); } try { (function () { ... })(); } catch (e) { console.log("EXCEPTION CAUGHT:", e); } ,但当然这也会导致程序立即退出。

所以在这一点上,我想留下约10秒,让用户在退出之前对exception进行查看或截图。

我想我应该只是使用阻塞sleep()通过npm模块,但我发现在testing中设置超时也似乎工作。 (也就是说,如果内build的东西工作,为什么还要用模块?)我猜这个意义不大,但是我只是好奇它是否指定某个节点实际上等待所有的超时在退出之前完成,所以我可以安全地做到这一点。

一般情况下,节点会在正常退出之前等待所有的超时。 调用process.exit()将在超时之前退出。

细节是libuv的一部分,但文档对此做了一个模糊的评论:

http://nodejs.org/api/all.html#all_ref

你可以调用ref()来显式的请求定时器把程序打开

把所有的事实放在一起,默认setTimeout被devise为保持事件循环打开(所以如果这是唯一的事情,程序将等待)。 您可以通过编程禁用或重新启用该行为。

迟到的答案,但肯定是的 – Nodejs将等待setTimeout完成 – 请参阅此文档 。 巧合的是,还有一种方法是等待setTimeout,也就是通过从setTimeoutsetInterval返回的对象上调用unref

总结一下:如果你希望Nodejs等待超时被调用,那么你就不需要做任何事情。 如果您希望Nodejs 等待特定的超时,请调用unref

如果节点没有等待所有setTimeoutsetInterval调用完成,那么您将无法在简单的脚本中使用它们。

一旦告诉节点侦听一个事件,就像使用setTimeout或者一些asynchronousI / O调用一样,事件循环将循环直到被告知退出。

而不是将所有内容都包含在try/catch你可以绑定一个事件监听器来处理,就像文档中的例子一样:

 process.on('uncaughtException', function(err) { console.log('Caught exception: ' + err); }); setTimeout(function() { console.log('This will still run.'); }, 500); // Intentionally cause an exception, but don't catch it. nonexistentFunc(); console.log('This will not run.'); 

uncaughtException事件中,您可以添加setTimeout在10秒后退出:

 process.on('uncaughtException', function(err) { console.log('Caught exception: ' + err); setTimeout(function(){ process.exit(1); }, 10000); }); 

如果这个exception是可以从中恢复的,那么您可能需要查看以下域: http : //nodejs.org/api/domain.html

编辑:

实际上可能还有另一个问题:你的客户端应用程序没有做足够的(或任何?)日志logging。 您可以使用log4js-node写入临时文件或某个特定于应用程序的位置。

简单的解决scheme:

  • 创build一个启动nodejs的批处理(.bat)文件
  • 做一个捷径

为什么这是最好的。 这样你的客户端就可以在命令行中运行nodejs。 即使nodejs程序返回,命令行也不会发生。

制作bat文件:

  1. 制作一个文本文件
  2. START cmd.exe /k "node abc.js"
  3. 保存
  4. 将它重命名为abc.bat
  5. 做一个快捷方式或其他。
  6. 打开它将打开CommandLine并运行nodejs文件。

使用settimeout这是一个坏主意。

奇怪的是当你调用process.exit()或者有一个未捕获的exception,正如Jim Schubert指出的那样。 除此之外,节点将等待超时完成。

节点确实记得定时器,但只有当它可以跟踪它们。 至less那是我的经验。

如果在箭头/匿名函数中使用setTimeout ,我会build议跟踪数组中的定时器,例如:

 => { timers.push(setTimeout(doThisLater, 2000)); } 

并确保let timers = []; 不是以一种将会消失的方法来设定的,即全球性的。