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


Posted in Javascript onMay 08, 2014

在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 相关文章推荐
js实现翻页后保持checkbox选中状态的实现方法
Nov 03 Javascript
javascript标签在页面中的位置探讨
Apr 11 Javascript
JQuery AJAX 中文乱码问题解决
Jun 05 Javascript
解决JS中乘法的浮点错误的方法
Jan 03 Javascript
node.js中的fs.chmodSync方法使用说明
Dec 18 Javascript
js实现获取当前时间是本月第几周的方法
Aug 11 Javascript
浅析JS操作DOM的一些常用方法
May 13 Javascript
jQuery UI Grid 模态框中的表格实例代码
Apr 01 jQuery
JavaScript实现简单的树形菜单效果
Jun 23 Javascript
ES6学习教程之Map的常用方法总结
Aug 03 Javascript
vue axios请求超时的正确处理方法
Apr 02 Javascript
Angular2实现的秒表及改良版示例
May 10 Javascript
Js Jquery创建一个弹出层可加载一个页面
May 08 #Javascript
一个html5播放视频的video控件只支持android的默认格式mp4和3gp
May 08 #Javascript
js 设置缓存及获取设置的缓存
May 08 #Javascript
javascript实现的一个带下拉框功能的文本框
May 08 #Javascript
javascript解析json数据的3种方式
May 08 #Javascript
Javascript异步编程模型Promise模式详细介绍
May 08 #Javascript
JS获取随机数函数可自定义最小值最大值
May 08 #Javascript
You might like
Zerg基本策略
2020/03/14 星际争霸
PHP 金额数字转换成英文
2010/05/06 PHP
php查看一个变量的占用内存的实例代码
2020/03/29 PHP
jQuery 全选效果实现代码
2009/03/23 Javascript
基于jQuery的前端数据通用验证库
2011/08/08 Javascript
javascript常用正则表达式汇总
2015/07/31 Javascript
JavaScript学习笔记之数组的增、删、改、查
2016/03/23 Javascript
jQuery 更改checkbox的状态,无效的解决方法
2016/07/22 Javascript
浅谈在fetch方法中添加header后遇到的预检请求问题
2017/08/31 Javascript
jQuery ajax读取本地json文件的实例
2017/10/31 jQuery
用最少的JS代码写出贪吃蛇游戏
2018/01/12 Javascript
ES6 迭代器(Iterator)和 for.of循环使用方法学习(总结)
2018/02/08 Javascript
JavaScript实现表单注册、表单验证、运算符功能
2018/10/15 Javascript
小程序实现点击tab切换左右滑动
2020/11/16 Javascript
npm全局环境变量配置详解
2020/12/15 Javascript
python实现在目录中查找指定文件的方法
2014/11/11 Python
Python中操作文件之write()方法的使用教程
2015/05/25 Python
python中requests小技巧
2017/05/10 Python
使用pandas批量处理矢量化字符串的实例讲解
2018/07/10 Python
Python Web框架之Django框架cookie和session用法分析
2019/08/16 Python
Django 实现Admin自动填充当前用户的示例代码
2019/11/18 Python
Python TKinter如何自动关闭主窗口
2020/02/26 Python
python异步Web框架sanic的实现
2020/04/27 Python
python随机模块random的22种函数(小结)
2020/05/15 Python
用python实现名片管理系统
2020/06/18 Python
乌克兰的第一家手表店:Deka
2020/03/05 全球购物
Android面试题及答案
2015/09/04 面试题
会计专业推荐信
2013/10/29 职场文书
手机被没收检讨书
2014/02/22 职场文书
放射科岗位职责
2015/02/14 职场文书
倡议书的格式写法
2015/04/28 职场文书
我的生日感言
2015/08/03 职场文书
化工生产实习心得体会
2016/01/22 职场文书
工作建议书范文
2019/07/08 职场文书
什么是创业计划书?什么是商业计划书?这里一一解答
2019/07/12 职场文书
详解JAVA的控制语句
2021/11/11 Java/Android