setInterval计时器不准的问题解决方法

 更新时间:2014年05月08日 15:45:32   作者:   我要评论

在js中如果打算使用setInterval进行倒数,计时等功能,往往是不准确的,针对这个问题,本文有个不错的解决方案
在js中如果打算使用setInterval进行倒数,计时等功能,往往是不准确的,因为setInterval的回调函数并不是到时后立即执行,而是等系算资源空闲下来后才会执行.而下一次触发时间则是在setInterval回调函数执行完毕之后才开始计时,所以如果setInterval内执行的计算过于耗时,或者有其他耗时任务在执行,setInterval的计时会越来越不准,延迟很厉害.

下面的代码可以说明这个问题
复制代码 代码如下:

var startTime = new Date().getTime();
var count = 0;
//耗时任务
setInterval(function(){
var i = 0;
while(i++ < 100000000);
}, 0);
setInterval(function(){
count++;
console.log(new Date().getTime() - (startTime + count * 1000));
}, 1000);

代码里输出了setInterval触发时间和应该正确触发时间的延迟毫秒数
复制代码 代码如下:

176
340
495
652
807
961
1114
1268
1425
1579
1734
1888
2048
2201
2357
2521
2679
2834
2996
......

可以看到延迟是越来越严重的.

为了在js里可以使用相对准确的计时功能,我们可以
复制代码 代码如下:

var startTime = new Date().getTime();
var count = 0;
setInterval(function(){
var i = 0;
while(i++ < 100000000);
}, 0);
function fixed() {
count++;
var offset = new Date().getTime() - (startTime + count * 1000);
var nextTime = 1000 - offset;
if (nextTime < 0) nextTime = 0;
setTimeout(fixed, nextTime);

console.log(new Date().getTime() - (startTime + count * 1000));
}
setTimeout(fixed, 1000);

代码里,通过1000(也就是周期时间)减去当前时间和准确时间的差距,来算出下次触发的时间,从而修正了当前触发的延迟.

下面是输出
复制代码 代码如下:

186
200
230
271
158
899
900
899
900
899
899
899
902
899
418
202
232
266
145
174
192
214
242
268
149
179
214
......

可以看到虽然触发时间并非绝对准确,但由于每次触发都进行及时修正,所以并没有造成误差积累.

相关文章

  • Ionic2系列之使用DeepLinker实现指定页面URL

    Ionic2系列之使用DeepLinker实现指定页面URL

    这篇文章主要介绍了Ionic2系列之使用DeepLinker实现指定页面URL的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2016-11-11
  • js判断一点是否在一个三角形内

    js判断一点是否在一个三角形内

    判断一个点是否在一个三角行内的代码
    2008-02-02
  • ppk谈JavaScript style属性

    ppk谈JavaScript style属性

    JavaScript允许你改变站点的CSS表示层。如果想把用户的眼球吸引到那些你希望他们关注的页面元素上,改变样式是极佳的(也是很普遍的)方式。
    2008-10-10
  • 一个JS的日期格式化算法示例

    一个JS的日期格式化算法示例

    本文为大家介绍下一个JS的日期格式化算法,具体实现如下,感兴趣的朋友可以参考下,希望对大家有所帮助
    2013-07-07
  • js鼠标、键盘事件实例代码

    js鼠标、键盘事件实例代码

    js 鼠标、键盘的几个事件的例子
    2008-07-07
  • 详解堆的javascript实现方法

    详解堆的javascript实现方法

    最近因为工作需要,要深入的学习JavaScript,发现如果囫囵吞枣印象就是不深刻,自己去练习一下才能慢慢有点感觉。本文主要是详解堆的javascript实现方法,另外堆排序对我们来说太耳熟而又少用的情况下,本文当作一次复习。感兴趣的朋友们下面来一起看看吧。
    2016-11-11
  • 省市选择的简单实现(基于zepto.js)

    省市选择的简单实现(基于zepto.js)

    下面小编就为大家带来一篇省市选择的简单实现(基于zepto.js)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随想过来看看吧
    2016-06-06
  • 11行JS代码制作二维码生成功能

    11行JS代码制作二维码生成功能

    本篇文章给大家分享了用11行简单的JS代码制作出二维码生成的简单功能,有兴趣的朋友参考下。
    2018-03-03
  • Cookie 小记

    Cookie 小记

    Cookie 经常用,也就是把关键信息记录进去,确认不在保留信息,则设置使之过期。
    2010-04-04
  • JavaScript实现与使用发布/订阅模式详解

    JavaScript实现与使用发布/订阅模式详解

    这篇文章主要介绍了JavaScript实现与使用发布/订阅模式,较为详细的分析了发布/订阅模式的概念、原理并结合实例形式分析了javascript实现与使用发布/订阅模式的相关操作技巧,需要的朋友可以参考下
    2019-01-01

最新评论