ufk*_*ufk 3 javascript setinterval node.js
我想每秒运行一次函数,而函数本身需要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
);
Run Code Online (Sandbox Code Playgroud)
每次迭代都如我在公式中所述:
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)
Run Code Online (Sandbox Code Playgroud)
文档没有说明此行为。我认为的结果是,无论间隔函数的执行花费多少时间,每次迭代都会在1秒后执行。
这是怎么回事?
任何有关此问题的信息将不胜感激。
谢谢!
使用Nodejs 6.3.0
在浏览器上尝试过此代码...谷歌浏览器...在这里,间隔每3秒执行一次,仍然很奇怪。
感谢您的所有评论,最后一件事还不清楚。为什么在NodeJS中,当我将setInterval()设置为1秒,并且函数执行需要3秒时,为什么下一次执行是7秒而不是4秒甚至3秒。对我来说,这似乎是很奇怪的行为。这是可以接受的行为吗?
文档没有说明此行为
NodeJS的特征文档setInterval几乎没有说明其行为,只是重复了任务。
我认为的结果是,无论间隔函数的执行花费多少时间,每次迭代都会在1秒后执行
如果您的意思是执行可能重叠,则不能使用NodeJS。它在单个线程上运行您的代码。
如果您希望每次迭代都在最后一次完成之后运行一秒钟,那么这不是setInterval传统上的工作方式。setInterval传统上,根据所使用的实现,它至少具有两种不同的行为:在当前迭代的开始处调度下一个迭代,或在当前迭代的末尾调度下一个迭代。那只是在浏览器上。从那时起,它已针对浏览器进行了标准化,但是NodeJS不是浏览器,并且不需要以相同的方式工作。(实际上,它也没有其他方式:在浏览器上,setInterval要求返回一个数字;在NodeJS上,它返回一个对象。)请记住,计时器不是JavaScript的功能,而是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);
Run Code Online (Sandbox Code Playgroud)
并运行一个示例(使用Node v6.2.2):
1468396730618:勾号 1468396730619:等待400毫秒 1468396731020:416毫秒后退出回调 1468396731637:勾号(617ms) 1468396731637:等待500ms 1468396732137:500毫秒后退出回调 1468396732837:勾号(700ms) 1468396732837:等待900ms 1468396733737:900毫秒后退出回调 1468396734837:勾号(1100ms) 1468396734837:等待300毫秒 1468396735137:300毫秒后退出回调 1468396735637:勾号(500ms) 1468396735637:等待700ms 1468396736337:700毫秒后退出回调 1468396737237:勾号(900ms) 1468396737237:等待800毫秒 1468396738037:在800毫秒后退出回调 1468396739036:勾号(999ms) 1468396739036:等待900ms 1468396739936:900毫秒后退出回调 1468396741036:勾号(1100ms) 1468396741036:等待700ms 1468396741736:700毫秒后退出回调 1468396742636:勾号(900ms) 1468396742636:等待200毫秒 1468396742836:200毫秒后退出回调 1468396743236:勾号(400ms)
如我们所见,它一直在等待上一次迭代的长度加上我给的间隔: