nodejs中的setInterval奇怪行为

编程入门 行业动态 更新时间:2024-10-27 16:27:05
本文介绍了nodejs中的setInterval奇怪行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我想每秒运行一次函数,函数本身需要 3 秒才能执行.结果是每个间隔在*2+

我编写了以下示例代码:

var seconds = 3;设置间隔(功能(){console.info(new Date().toString());var waitTill = new Date(new Date().getTime() + seconds * 1000);while(waitTill > new Date()){}},1000);

并且每次迭代都如我在公式中所述:

2016 年 7 月 13 日星期三 09:49:07 GMT+0300 (IDT)2016 年 7 月 13 日星期三 09:49:14 GMT+0300 (IDT)2016 年 7 月 13 日星期三 09:49:21 GMT+0300 (IDT)2016 年 7 月 13 日星期三 09:49:28 GMT+0300 (IDT)

文档没有说明这种行为.我认为的结果是,无论间隔函数的执行需要多少时间,每次迭代都会在 1 秒后执行.

怎么回事?

任何有关该问题的信息将不胜感激.

谢谢!

使用 Nodejs 6.3.0

更新

在浏览器上试过这段代码...谷歌浏览器...这里间隔每3秒执行一次,这仍然很奇怪.

更新

感谢您的所有评论,最后一件事还不清楚.为什么在 NodeJS 中,当我将 setInterval() 设置为 1 秒,并且函数执行需要 3 秒时,为什么下一次执行是 7 秒而不是 4 秒甚至 3 秒.这对我来说似乎很奇怪.这是可以接受的行为吗?

解决方案

文档没有说明这种行为

NodeJS 的 setInterval 文档几乎没有任何关于它的行为,除此之外它会重复任务.

我认为的结果是,无论间隔函数的执行需要多少时间,每次迭代都会在1秒后执行

如果你的意思是你可以有重叠的执行,你不能在 NodeJS 中;它在单个线程上运行您的代码.

如果您的意思是希望每次迭代在最后一次完成后运行一秒钟,那么 setInterval 传统上不是这样工作的.setInterval 传统上至少有两种不同的行为,具体取决于您使用的实现:在当前迭代的开始调度下一次迭代,或在 调度它>end 当前的.这只是在浏览器上.这是因为 已为浏览器标准化,但 NodeJS 不是t 浏览器,不需要以相同的方式工作.(事实上​​,它也不是以另一种方式:在浏览器上,setInterval 需要返回一个数字;在 NodeJS 上,它返回一个对象.)请记住,计时器不是JavaScript,它们是宿主环境的一个特性.

相反,要让它在之前完成后一秒(大约)再次运行,请在函数末尾使用 setTimeout 安排下一秒运行.

重新

为什么在 NodeJS 中,当我将 setInterval() 设置为 1 秒,并且函数执行需要 3 秒时,为什么下一次执行是 7 秒而不是 4 秒甚至 3 秒.这对我来说似乎很奇怪.这是可以接受的行为吗?

是的.这很奇怪和令人惊讶(在我看来),但是 NodeJS 为 setInterval 确定了自己的行为,所以它可以接受.在我的实验中(如下),它似乎测量了您的函数的前一次执行所花费的时间,然后将其添加到计时器长度中,使其在它之前是 lastExecutionLength + desiredInterval再次开火.这与浏览器的规范明显不同,但同样,NodeJS 不是浏览器.

这是我的测试脚本:

let counter = 0;让 timeAtEndOfLastExecution = 0;让计时器=空;功能日志(味精){console.log(Date.now() + ": " + msg);}功能滴答(){让开始 = Date.now();如果(timeAtEndOfLastExecution){log("tick (" + (Date.now() - timeAtEndOfLastExecution) + "ms)");} 别的 {日志(滴答");}如果(++计数器== 10){清除间隔(定时器);} 别的 {让等待 = 200 + (Math.floor(8 * Math.random()) * 100);日志(等待"+等待+毫秒");让 stopWaiting = Date.now() + 等待;而 (Date.now() < stopWaiting) {//忙等待}log("退出回调" + (Date.now() - start) + "ms");timeAtEndOfLastExecution = Date.now();}}timer = setInterval(tick, 200);

以及一个示例运行(使用 Node v6.2.2):

1468396730618:打勾1468396730619:等待400ms1468396731020:416ms 后退出回调1468396731637:滴答(617ms)1468396731637:等待500ms1468396732137:500 毫秒后退出回调1468396732837:滴答(700 毫秒)1468396732837:等待900ms1468396733737:900 毫秒后退出回调1468396734837:滴答(1100毫秒)1468396734837:等待300ms1468396735137:300 毫秒后退出回调1468396735637:滴答(500毫秒)1468396735637:等待700ms1468396736337:700 毫秒后退出回调1468396737237:滴答(900 毫秒)1468396737237:等待800ms1468396738037:800 毫秒后退出回调1468396739036:滴答(999ms)1468396739036:等待900ms1468396739936:900 毫秒后退出回调1468396741036:滴答(1100毫秒)1468396741036:等待700ms1468396741736:700 毫秒后退出回调1468396742636:滴答(900 毫秒)1468396742636:等待200ms1468396742836:200 毫秒后退出回调1468396743236:滴答(400毫秒)

正如我们所见,它一直在等待前一次迭代的长度加上我给出的间隔:

  • 第一次回调总共耗时 416 毫秒;下一个在返回后 617 毫秒开始
  • 第二次回调耗时 500 毫秒;下一个在返回后 700 毫秒开始
  • 第三次回调900ms;下一个在返回后 1100 毫秒开始

I want to run a function once every second, and the function itself takes 3 seconds to execute. the results are that each interval is executed at a difference of <function execution time>*2+<setInterval delay>

I wrote the following sample code:

var seconds = 3; setInterval( function(){ console.info(new Date().toString()); var waitTill = new Date(new Date().getTime() + seconds * 1000); while(waitTill > new Date()){} },1000 );

and each iteration is as I stated in the formula:

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)

the documentation doesn't state this behaviour. the results that I thought that will be is that each iteration will execute after 1 second no matter how much time the execution of the interval function takes.

what's going on?

any information regarding the issue would be greatly appreciated.

thanks!

using Nodejs 6.3.0

update

tried this code on the browser... google chrome... here the interval executes every 3 seconds, which is still weird.

update

thanks for all of your comments, one last thing that's not clear. why in NodeJS, when I have setInterval() set to 1 second, and the function execution takes 3 seconds, why the next execution is 7 seconds instead of 4 seconds or even 3 seconds. that seems really strange behaviour for me. is that an acceptable behaviour ?

解决方案

the documentation doesn't state this behavior

NodeJS's documentation for setInterval characteristically states virtually nothing about its behavior, other than that it will repeat the task.

the results that I thought that will be is that each iteration will execute after 1 second no matter how much time the execution of the interval function takes

If you mean you could have overlapping executions, you can't in NodeJS; it runs your code on a single thread.

If you mean you expected each iteration to run a second after the last completed, that's not how setInterval traditionally works. setInterval has traditionally had at least two different behaviors depending on which implementation you were using: Scheduling the next iteration at the beginning of the current one, or scheduling it at the end of the current one. And that's just on browsers. It's since been standardized for browsers, but NodeJS isn't a browser and isn't required to work the same way. (And in fact, it doesn't in another way as well: On browsers, setInterval is required to return a number; on NodeJS, it returns an object.) Remember that timers are not a feature of JavaScript, they're a feature of the host environment.

Instead, to get it to run again a second (roughly) after it finished previously, use setTimeout at the end of the function to schedule the next one to run a second later.

Re your edit:

why in NodeJS, when I have setInterval() set to 1 second, and the function execution takes 3 seconds, why the next execution is 7 seconds instead of 4 seconds or even 3 seconds. that seems really strange behavior for me. is that an acceptable behavior ?

Yes. It's strange and surprising (in my view), but NodeJS determines its own behavior for setInterval, so it's acceptable. In my experiments (below), it appears to measure how long the previous execution of your function took, then add that to the timer length so that it's lastExecutionLength + desiredInterval before it fires it again. That's markedly at variance with the spec for browsers, but again, NodeJS isn't a browser.

Here's my test script:

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);

And a sample run (with 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)

As we can see, it's consistently waiting the length of the previous iteration plus the interval I gave:

  • First callback took a total of 416ms; the next started 617ms after it returned
  • Second callback took 500ms; the next started 700ms after it returned
  • Third callback 900ms; the next started 1100ms after it returned

更多推荐

nodejs中的setInterval奇怪行为

本文发布于:2023-10-14 11:34:44,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1490955.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:奇怪   nodejs   setInterval

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!