简单计时器和setInterval

3

如何在JS中创建定时器是最佳方式?

到目前为止,我一直在使用以下方法:

var sec = 0;
setInterval(function (){sec +=1}, 1000);

我注意到,当我需要毫秒级的响应时,速度会变得非常慢。在浏览器标签切换时,它完全停止了。

var milisec = 0;
setInterval(function (){milisec +=1}, 1);

我正在寻找更好的处理方法,这种方法在浏览器窗口改变时仍然有效。

你想要做什么? - James Donnelly
https://developer.mozilla.org/en-US/docs/Web/API/window.requestAnimationFrame - Sirko
浏览器最多只有4-10毫秒的setInterval分辨率。不同的浏览器还存在其他限制 - Sani Huttunen
2个回答

4
使用毫秒作为计时器的分辨率不够大。即使将间隔设置为1毫秒,大多数情况下回调函数每秒也只会被调用50到250次左右。可以参考Sani Huttunen提到的“浏览器中的计时器分辨率”(见链接:Timer resolution in browsers)进行解释。
使用1000毫秒会更好一些。但是当选项卡处于非活动状态时,计时器仍然不会触发,并且当CPU繁忙或页面上运行另一个脚本时,计时器可能会延迟执行。
一种解决方案是不递增计数器,而是测试自上次调用计时器以来实际经过的时间。这样,即使在间隔期间被延迟或暂停了,时间仍然保持准确。
此片段将记住开始日期,并在每个计时器间隔上,将秒数和毫秒数更新为当前时间与开始时间之间的差异。
var start = new Date();
var milliseconds = 0;
var seconds = 0;
setInterval(function()
{
    var now = new Date();
    milliseconds = now.getTime() - start.getTime();
    seconds = round(milliseconds / 1000);
}, 1000);

我已将时间间隔再次设置为1000。你可以将它设置得更短,但这会消耗更多的性能。
相关问题:如何使在Chrome中一个标签处于不活动状态时setInterval也能正常工作?

你的答案实际上与设置间隔没有太大区别-但它启发我寻找更新事物的替代方法。我将我的解决方案作为答案分享,供日后参考。 - Mia
2
我的答案也有一个设置间隔。那部分是相同的。不同之处在于你如何计算哪个(毫秒)秒。 - GolezTrol
一个很好的例子,说明为什么一个好的问题描述对于一个问题是相关的。显然,你根本不需要一个计时器,你只需要知道自页面加载以来经过了多长时间。无论如何,答案帮助了你,这很重要。 - GolezTrol

0
基于 @goleztrol 的解决方案,我为我的情况创建了一个替代解决方案(它可能并不适用于每个人)。
我只需使用这个函数在需要的时候询问确切时间,以知道过去的确切毫秒数:
var start = new Date();
var msPassed = function() {
    var now = new Date();
    var ms = now.getTime() - start.getTime();
    return ms
}

msPassed(); //returns time passed in ms

我需要根据创建时经过的时间来定位对象,所以对于我的情况,这是一个完美的解决方案。但是,我的初始问题要求完美的计时器,而这不是。无论如何,这里是供将来参考的。

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