Node.JS:不会使进程保持运行的setTimeout

11

我想在这个进程中添加一个一小时的超时时间,以防止在流死锁的情况下无限期等待。唯一的问题是,如果我使用setTimeout,该进程就没有机会提前结束。

有没有一种方法可以在大约一个小时后强制退出超时,而不保持进程运行?或者我只能在使用process.exit和不使用此超时之间做出选择吗?

3个回答

21

我不知道 unref 何时被添加到Node中,但现在这是一种可能的解决方案。重用Matt的代码:

var timeoutId = setTimeout(callback, 3600000);
timeoutId.unref(); // Now, Node won't wait for this timeout to complete if it needs to exit earlier.

文档中说道:
在使用setTimeout时,如果你使用unref方法,会创建一个单独的定时器来唤醒事件循环,创建过多的定时器可能会对事件循环的性能产生不良影响--所以要谨慎使用。不要滥用它。

1
很好,我之前没有听说过这个。unref在Node 0.9.1中添加。 - Matt Ball

8

如果你保存了setTimeout返回的值,你总是可以在它触发之前使用clearTimeout来取消它,就像这样:

var timeoutId = setTimeout(callback, 3600000); // 1 hour

// later, before an hour has passed
clearTimeout(timeoutId);

我希望有一种不需要使用 clearTimeout 的方法,但我可以不用它。 - 700 Software
1
有没有任何原因不能使用clearTimeout?是性能或信仰问题吗? - Romick
@Romick,这样做有很好的理由。如果您创建了一个使用超时(或间隔 - unref() 对于间隔也适用)的方法或库,则不希望您代码的消费者了解您代码的内部细节,并要求他们调用close或shutdown方法来清除您的计时器。我刚刚创建了一些代码,用于跟踪世界各地国家夏令时的不断变化的规则。默认情况下,我的代码每天轮询一次以查找更新。使用unref(),我的用户无需担心杀死我使用的间隔。 - kshetline

1

可能的解决方案是使用一个特性,它被实现为process.watchers(),但我不知道它是否已经包含在发布的版本中。截至本帖发布时,拉取请求仍然处于打开状态。

但一般来说,您可以编写一个自定义的setTimeout函数,将所有超时添加到计数器中,在超时到达回调之前,从计数器中删除。

然后创建一个持续的间隔,该间隔会检查并注意到所有行走者都只是由您的自定义函数设置的超时。

当它注意到这一点时,它会(清除所有这些超时,导致)退出。

当然,这并不是很好,因为

  • 这个概念还没有被证明。(我不知道process.watchers()会返回什么样的数据,或者它是否已经可用)
  • 间隔是一种轮询方法。(如果您想要立即返回并且同时保持低CPU使用率,则不太好)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接