13

考虑:

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

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

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

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

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

因此,在这一点上,我想留出大约 10 秒的时间让用户在异常退出之前对其进行查看或截屏。

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

4

6 回答 6

10

一般来说,节点会在正常退出之前等待所有超时触发。调用process.exit()将在超时之前退出。

详细信息是libuv的一部分,但文档对此做出了含糊的评论:

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

您可以调用 ref() 显式请求计时器保持程序打开

将所有事实放在一起,setTimeout默认情况下旨在使事件循环保持打开状态(因此,如果这是唯一未决的事情,则程序将等待)。您可以以编程方式禁用或重新启用该行为。

于 2013-08-05T03:50:06.797 回答
5

迟到的答案,但肯定的- Nodejs 将等待 setTimeout 完成 - 请参阅此文档。巧合的是,还有一种方法可以不用等待 setTimeout,那就是调用unrefsetTimeoutor返回的对象setInterval

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

于 2014-01-24T10:53:00.837 回答
1

如果 node 没有等待 allsetTimeoutsetInterval调用完成,您将无法在简单的脚本中使用它们。

一旦你告诉 node 去监听一个事件,就像使用setTimeout或一些异步 I/O 调用一样,事件循环将循环直到它被告知退出。

try/catch您可以将事件侦听器绑定到处理,就像文档中的示例一样,而不是将所有内容包装在 a中:

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下,您可以添加setTimeout10 秒后退出:

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

如果您可以从中恢复此异常,您可能需要查看域:http ://nodejs.org/api/domain.html

编辑:

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

于 2013-08-05T03:52:47.687 回答
1

简单的方法解决方案:

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

为什么这是最好的。这样,您的客户端将在命令行中运行 nodejs。即使 nodejs 程序返回,命令行也不会发生任何事情。

制作bat文件:

  1. 制作一个文本文件
  2. START cmd.exe /k "node abc.js"
  3. 保存
  4. 将其重命名为 abc.bat
  5. 做一个捷径什么的。
  6. 打开它将打开命令行并运行 nodejs 文件。

为此使用 settimeout 是个坏主意。

于 2013-08-05T03:44:24.010 回答
0

process.exit()正如 Jim Schubert 所指出的那样,奇怪的是当您调用或出现未捕获的异常时。除此之外,节点将等待超时完成。

于 2013-08-05T05:54:39.130 回答
0

Node 确实记得计时器,但前提是它可以跟踪它们。至少这是我的经验。

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

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

并确保let timers = [];未设置在将消失的方法中,即全局。

于 2016-07-03T17:31:00.430 回答