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 相关文章推荐
JavaScript 变量作用域分析
Jul 04 Javascript
利用javaScript实现点击输入框弹出窗体选择信息
Dec 11 Javascript
把jQuery的类、插件封装成seajs的模块的方法
Mar 12 Javascript
jQuery插件scroll实现无缝滚动效果
Apr 27 Javascript
jQuery CSS3自定义美化Checkbox实现代码
May 12 Javascript
AngularJs解决跨域问题案例详解(简单方法)
May 19 Javascript
js处理层级数据结构的方法小结
Jan 17 Javascript
浅析Node.js非对称加密方法
Jan 29 Javascript
解决jQuery使用append添加的元素事件无效的问题
Aug 30 jQuery
vue里如何主动销毁keep-alive缓存的组件
Mar 21 Javascript
p5.js临摹旋转爱心
Oct 23 Javascript
vue-router重写push方法,解决相同路径跳转报错问题
Aug 07 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
PHP+MYSQL的文章管理系统(二)
2006/10/09 PHP
NOT NULL 和NULL
2007/01/15 PHP
PHP中ID设置自增后不连续的原因分析及解决办法
2016/08/21 PHP
php魔术方法功能与用法实例分析
2016/10/19 PHP
PHP实现的策略模式简单示例
2017/08/25 PHP
DOM基础教程之事件类型
2015/01/20 Javascript
JS清除选择内容的方法
2015/01/29 Javascript
JavaScript检查弹出窗口是否被阻拦的方法技巧
2015/03/13 Javascript
javascript实现3D变换的立体圆圈实例
2015/08/06 Javascript
jQuery Html控件基本操作(日常收集整理)
2016/03/11 Javascript
Jquery Easyui日历组件Calender使用详解(23)
2016/12/18 Javascript
详解基于webpack和vue.js搭建开发环境
2017/04/05 Javascript
关于Angular2 + node接口调试的解决方案
2017/05/28 Javascript
layer子层给父层页面元素赋值,以达到向父层页面传值的效果实例
2017/09/22 Javascript
vue2.0 如何把子组件的数据传给父组件(推荐)
2018/01/15 Javascript
js函数和this用法实例分析
2020/03/13 Javascript
js调用网络摄像头的方法
2020/12/05 Javascript
python局域网ip扫描示例分享
2014/04/03 Python
python SSH模块登录,远程机执行shell命令实例解析
2018/01/12 Python
python接口自动化(十六)--参数关联接口后传(详解)
2019/04/16 Python
Python随机函数库random的使用方法详解
2019/08/21 Python
pytest中文文档之编写断言
2019/09/12 Python
python图形绘制奥运五环实例讲解
2019/09/14 Python
python爬虫学习笔记之Beautifulsoup模块用法详解
2020/04/09 Python
详解pandas获取Dataframe元素值的几种方法
2020/06/14 Python
科颜氏加拿大官方网站: Kiehl’s加拿大
2016/08/16 全球购物
乐高积木玩具美国官网:LEGO Shop US
2016/09/16 全球购物
美国生鲜及杂货电商:FreshDirect
2018/01/29 全球购物
日本航空官方网站:JAL
2019/06/19 全球购物
Hammitt官网:设计师手袋
2020/05/23 全球购物
2014两会学习心得:榜样精神伴我行
2014/03/17 职场文书
初中生评语大全
2014/04/24 职场文书
感恩母亲节演讲稿
2014/05/07 职场文书
2015年高三年级组工作总结
2015/07/21 职场文书
检举信的写法
2019/04/10 职场文书
如何制定一份可行的计划!
2019/06/21 职场文书