Node.js setTimeout在长时间运行的函数中引入延迟

Node.js setTimeout在长时间运行的函数中引入延迟,node.js,Node.js,下面的代码执行一个长时间运行的函数(保持简单的睡眠),然后使用setTimeout再次调用自己。我正在使用nodejs5.1.0 var start_time = Math.ceil(new Date() /1000) function sleep(delay) { var start = new Date().getTime(); while (new Date().getTime() < start + delay); } function iteration(){ co

下面的代码执行一个长时间运行的函数(保持简单的睡眠),然后使用setTimeout再次调用自己。我正在使用nodejs5.1.0

var start_time = Math.ceil(new Date() /1000)
function sleep(delay) {
  var start = new Date().getTime();
  while (new Date().getTime() < start + delay);
}

function iteration(){
  console.log("sleeping at :", Math.ceil(new Date()/1000 - start_time));
  sleep(10000); // sleep 10 secs
  console.log("waking up at:", Math.ceil(new Date()/1000 - start_time));
  setTimeout(iteration, 0); 
}

iteration();
正如您所看到的,程序在第一次醒来后立即休眠(这是我所期望的),但不是在那之后。事实上,它在醒来和睡觉之间正好再等10秒钟

如果我使用setImmediate,事情会很好。知道我错过了什么吗

编辑:

注:

在我的实际代码中,我有一个复杂的长算法,而不是一个简单的睡眠函数。上面的代码只是在一个更简单的用例中重现了这个问题。 这意味着我不能使用setTimeout(iteraton,10000)

2-我之所以使用延迟为0的setTimeout,是因为我的代码阻塞NodeJ的时间太长,以至于其他较小的任务会延迟。通过执行setTimeout,nodejs返回事件循环以执行这些小任务,然后继续处理我的长时间运行的主要代码

3-我完全理解setInterval(函数,0)将尽快运行,而不是在之后立即运行,但是这并不能解释为什么它会以10秒的延迟运行,因为nodejs没有做任何其他事情

4-我的Chrome代码运行没有任何问题。Nodejs bug?

首先查看:

请务必注意,您的回调可能不会被调用 在精确的延迟毫秒内-Node.js不保证 回调将触发的确切时间,以及顺序 事情会发生的。将尽可能近距离调用回调 到指定的时间

要使函数更异步,可以进行如下操作:

function iteration(callback){
  console.log("sleeping at :", Math.ceil(new Date()/1000));
  sleep(10000); // sleep 10 secs
  console.log("waking up at:", Math.ceil(new Date()/1000));
  return setTimeout(callback(iteration), 0);      
}

iteration(iteration);
下一个问题是你的睡眠功能。您有一个while循环阻止所有node.js进程,以使node.js的setTimeout函数为您做一些事情

function sleep(delay) {
  var start = new Date().getTime();
  while (new Date().getTime() < start + delay);
}
功能睡眠(延迟){
var start=new Date().getTime();
while(new Date().getTime()
现在发生的是,你的睡眠功能正在阻止这个过程。它不仅发生在您直接调用函数时,而且也发生在node.js异步调用setTimeout后初始化函数范围时

这不是一个错误。它必须是这样的,因为在while循环中可能有迭代函数必须知道的东西。特别是在setTimeout之后调用它时。因此,首先检查sleep函数,并尽快调用该函数


问题更改后编辑的答案

这可能不是问题所在,但我看不到任何东西表明您可以这样使用(new Date()/1000)。。。您不应该使用getTime()还是now()?一个错误案例!我想知道这是setTimeout的节点实现,它是有缺陷的,还是整个V8。必须在Chrome控制台中检查。好的,所以在Chrome控制台中,问题不会出现。因此,这确实是node
setTimeout
实现的一个bug。
setTimeout(SOMEFUNC,0)
在存在之前就被使用过。@robertklep:是的,这正是需要setImmediate()的原因,因为行为不同。@apxp我编辑了我的帖子,以回答您对nodejs文档的评论,并直接或使用setTimeout second回调函数parameter@apxp我理解您所说的setTimeout初始化要调用的函数的上下文,但是初始化上下文意味着什么?因为它似乎在执行整个过程function@apxp我认为setTimeout调用的代码无关紧要。在chrome中,设置间隔按预期工作。。。
function sleep(delay) {
  var start = new Date().getTime();
  while (new Date().getTime() < start + delay);
}