我想每秒运行一次函数,函数本身需要3秒才能执行。结果是每个区间的执行差异为<function execution time>*2+<setInterval delay>
我写了以下示例代码:
var seconds = 3;
setInterval(
function(){
console.info(new Date().toString());
var waitTill = new Date(new Date().getTime() + seconds * 1000);
while(waitTill > new Date()){}
},1000
);
并且每次迭代都如我在公式中所述:
Wed Jul 13 2016 09:49:07 GMT+0300 (IDT)
Wed Jul 13 2016 09:49:14 GMT+0300 (IDT)
Wed Jul 13 2016 09:49:21 GMT+0300 (IDT)
Wed Jul 13 2016 09:49:28 GMT+0300 (IDT)
文档没有说明这种行为。我认为的结果是每次迭代将在1秒后执行,无论执行间隔函数需要多长时间。
发生了什么?
非常感谢有关该问题的任何信息。
谢谢!
使用Nodejs 6.3.0
在浏览器上尝试了这个代码... google chrome ...这里的间隔每3秒执行一次,这仍然很奇怪。
感谢您的所有评论,最后一件事情并不清楚。 为什么在NodeJS中,当我将setInterval()设置为1秒,并且函数执行需要3秒时,为什么下一次执行是7秒而不是4秒甚至3秒。这对我来说似乎很奇怪。这是一种可接受的行为吗?
答案 0 :(得分:5)
文档未说明此行为
NodeJS的documentation for setInterval
在特征上几乎没有说明它的行为,除了它将重复任务。
我认为的结果是每次迭代将在1秒后执行,无论执行间隔函数需要多长时间
如果你的意思是你可以有重叠的执行,你不能在NodeJS;它在一个线程上运行你的代码。
如果您的意思是您希望每次迭代在最后一次完成后运行一秒,那不是setInterval
传统的工作方式。 setInterval
传统上至少有两种不同的行为取决于您使用的实现:在当前的开始调度下一次迭代,或者在 end调度< / em>当前的一个。这只是在浏览器上。它来自been standardized for browsers,但NodeJS不是浏览器,不需要以相同的方式工作。 (事实上,它也不是另一种方式:在浏览器上,setInterval
需要返回一个数字;在NodeJS上,它返回一个对象。)请记住,定时器不是JavaScript的一个特性,它们是是主机环境的一个特征。
相反,为了让它在之前完成后再次(大致)再次运行,请在函数末尾使用setTimeout
来安排下一个运行一秒钟。
重新编辑:
为什么在NodeJS中,当我将setInterval()设置为1秒,并且函数执行需要3秒时,为什么下一次执行是7秒而不是4秒甚至3秒。这对我来说似乎很奇怪。这是一种可接受的行为吗?
是。这是奇怪和令人惊讶的(在我看来),但NodeJS确定了自己setInterval
的行为,所以它是可接受的。在我的实验(下面)中,它似乎可以测量上一次执行函数所花费的时间,然后将添加到计时器长度,以便在再次触发它之前它是lastExecutionLength + desiredInterval
。这显然与浏览器规范不符,但同样,NodeJS不是浏览器。
这是我的测试脚本:
let counter = 0;
let timeAtEndOfLastExecution = 0;
let timer = null;
function log(msg) {
console.log(Date.now() + ": " + msg);
}
function tick() {
let start = Date.now();
if (timeAtEndOfLastExecution) {
log("tick (" + (Date.now() - timeAtEndOfLastExecution) + "ms)");
} else {
log("tick");
}
if (++counter == 10) {
clearInterval(timer);
} else {
let wait = 200 + (Math.floor(8 * Math.random()) * 100);
log("waiting " + wait + "ms");
let stopWaiting = Date.now() + wait;
while (Date.now() < stopWaiting) {
// busy wait
}
log("exiting callback after " + (Date.now() - start) + "ms");
timeAtEndOfLastExecution = Date.now();
}
}
timer = setInterval(tick, 200);
运行示例(使用Node v6.2.2):
1468396730618: tick 1468396730619: waiting 400ms 1468396731020: exiting callback after 416ms 1468396731637: tick (617ms) 1468396731637: waiting 500ms 1468396732137: exiting callback after 500ms 1468396732837: tick (700ms) 1468396732837: waiting 900ms 1468396733737: exiting callback after 900ms 1468396734837: tick (1100ms) 1468396734837: waiting 300ms 1468396735137: exiting callback after 300ms 1468396735637: tick (500ms) 1468396735637: waiting 700ms 1468396736337: exiting callback after 700ms 1468396737237: tick (900ms) 1468396737237: waiting 800ms 1468396738037: exiting callback after 800ms 1468396739036: tick (999ms) 1468396739036: waiting 900ms 1468396739936: exiting callback after 900ms 1468396741036: tick (1100ms) 1468396741036: waiting 700ms 1468396741736: exiting callback after 700ms 1468396742636: tick (900ms) 1468396742636: waiting 200ms 1468396742836: exiting callback after 200ms 1468396743236: tick (400ms)
正如我们所看到的,它一直在等待上一次迭代的长度加上我给出的间隔: