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
......

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

相关文章

  • Javascript数组操作函数总结

    Javascript数组操作函数总结

    这篇文章主要给大家汇总介绍了Javascript数组操作函数,需要的朋友可以参考下
    2015-02-02
  • 十分钟打造AutoComplete自动完成效果代码

    十分钟打造AutoComplete自动完成效果代码

    十分钟打造山寨版谷歌AutoComplete,因为是十分钟打造出来的,所以只考虑表面效果,其他全部忽略,绝对的山寨。
    2009-12-12
  • 如何利用JS检查元素是否在视口内

    如何利用JS检查元素是否在视口内

    这篇文章主要给大家介绍了关于如何利用JS检查元素是否在视口内的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • js变量声明var使用与不使用的区别详解

    js变量声明var使用与不使用的区别详解

    今天小编就为大家分享一篇关于js变量声明var使用与不使用的区别详解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01
  • 微信小程序实现上传照片代码实例解析

    微信小程序实现上传照片代码实例解析

    这篇文章主要介绍了微信小程序实现上传照片代码实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-08-08
  • javascript将url中的参数加密解密代码

    javascript将url中的参数加密解密代码

    本文给大家分享一段给url参数加密解密的javascript代码,非常的好用,有需要的小伙伴直接拿走吧
    2014-11-11
  • JS实现悬浮球只在一侧滑动并且是横屏状态下

    JS实现悬浮球只在一侧滑动并且是横屏状态下

    这篇文章主要介绍了JS实现悬浮球只在一侧滑动 并且是横屏状态下,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-08-08
  • 微信小程序按钮点击跳转页面详解

    微信小程序按钮点击跳转页面详解

    这篇文章主要介绍了微信小程序按钮点击跳转页面,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-05-05
  • js实现C#的StringBuilder效果完整实例

    js实现C#的StringBuilder效果完整实例

    这篇文章主要介绍了js实现C#的StringBuilder效果,以完整实例形式分析总结了js实现C#的StringBuilder效果的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-12-12
  • json属性名为什么要双引号(个人猜测)

    json属性名为什么要双引号(个人猜测)

    json属性名为什么要双引号?更加规范,利于解析、避免class等关键字引起的不兼容问题,需要的朋友可以参考下
    2014-07-07

最新评论