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 相关文章推荐
关于jQuery $.isNumeric vs. $.isNaN vs. isNaN
Apr 15 Javascript
ExtJs中gridpanel分组后组名排序实例代码
Dec 02 Javascript
基于jQuery实现复选框的全选 全不选 反选功能
Nov 24 Javascript
基于jquery实现瀑布流布局
Jun 28 Javascript
Angular2学习笔记——详解路由器模型(Router)
Dec 02 Javascript
百度地图JavascriptApi Marker平滑移动及车头指向行径方向
Mar 13 Javascript
react.js 获取真实的DOM节点实例(必看)
Apr 17 Javascript
JS的函数调用栈stack size的计算方法
Jun 24 Javascript
小程序数据通信方法大全(推荐)
Apr 15 Javascript
VUE实现图片验证码功能
Nov 18 Javascript
JavaScript链式调用原理与实现方法详解
May 16 Javascript
详谈vue中router-link和传统a链接的区别
Jul 22 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
Zend Framework使用Zend_Loader组件动态加载文件和类用法详解
2016/12/09 PHP
利用PHP访问MySql数据库的逻辑操作以及增删改查的实例讲解
2017/08/30 PHP
javascript textContent与innerText的异同分析
2010/10/22 Javascript
JavaScript ( (__ = !$ + $)[+$] + ({} + $)[_/_] +({} + $)[_/_] )
2011/02/25 Javascript
node.js中的path.dirname方法使用说明
2014/12/09 Javascript
javascript实现图像循环明暗变化的方法
2015/02/25 Javascript
理解JavaScript表单的基础知识
2016/01/25 Javascript
基于HTML5上使用iScroll实现下拉刷新,上拉加载更多
2016/05/21 Javascript
点击按钮出现60秒倒计时的简单js代码(推荐)
2016/06/07 Javascript
学好js,这些js函数概念一定要知道【推荐】
2017/01/19 Javascript
vue组件发布到npm简单步骤
2017/11/30 Javascript
Flutter部件内部状态管理小结之实现Vue的v-model功能
2019/06/11 Javascript
原生js实现点击轮播切换图片
2020/02/11 Javascript
node.js使用zlib模块进行数据压缩和解压操作示例
2020/02/12 Javascript
解决vue+elementui项目打包后样式变化问题
2020/08/03 Javascript
在Python的Django框架中创建语言文件
2015/07/27 Python
Python的自动化部署模块Fabric的安装及使用指南
2016/01/19 Python
Python使用win32com实现的模拟浏览器功能示例
2017/07/13 Python
python嵌套字典比较值与取值的实现示例
2017/11/03 Python
python好玩的项目—色情图片识别代码分享
2017/11/07 Python
在双python下设置python3为默认的方法
2018/10/31 Python
详解python中__name__的意义以及作用
2019/08/07 Python
Python字典底层实现原理详解
2019/12/18 Python
新手入门学习python Numpy基础操作
2020/03/02 Python
python 检测nginx服务邮件报警的脚本
2020/12/31 Python
推荐10个CSS3 制作的创意下拉菜单效果
2014/02/11 HTML / CSS
武汉东之林科技有限公司机试
2013/09/17 面试题
综合素质的自我鉴定
2013/10/07 职场文书
2014年教师节寄语
2014/04/03 职场文书
2016年春节慰问信息
2015/03/25 职场文书
2015年法院工作总结范文
2015/04/28 职场文书
建国大业电影观后感
2015/06/01 职场文书
歼十出击观后感
2015/06/11 职场文书
Python多线程 Queue 模块常见用法
2021/07/04 Python
面试中老生常谈的MySQL问答集锦夯实基础
2022/03/13 MySQL
nginx七层负载均衡配置详解
2022/07/15 Servers