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 相关文章推荐
HTA版JSMin(省略修饰语若干)基于javascript语言编写
Dec 24 Javascript
node.js实现BigPipe详解
Dec 05 Javascript
jQuery取消ajax请求的方法
Jun 09 Javascript
jQuery+CSS实现的网页二级下滑菜单效果
Aug 25 Javascript
javascript检测flash插件是否被禁用的方法
Jan 14 Javascript
JavaScript学习小结之被嫌弃的eval函数和with语句实例详解
Aug 01 Javascript
BootStrap 图标icon符号图标glyphicons不正常显示的快速解决办法
Dec 08 Javascript
vue实现选项卡及选项卡切换效果
Apr 24 Javascript
vscode中vue-cli项目es-lint的配置方法
Jul 30 Javascript
jQuery实现ajax的嵌套请求案例分析
Feb 16 jQuery
layui-table对返回的数据进行转变显示的实例
Sep 04 Javascript
element表格翻页第2页从1开始编号(后端从0开始分页)
Dec 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
xml在joomla表单中的应用详解分享
2012/07/19 PHP
基于php和mysql的简单的dao类实现crud操作功能
2014/01/27 PHP
PHP伪静态Rewrite设置之APACHE篇
2014/07/30 PHP
PHP将Excel导入数据库及数据库数据导出至Excel的方法
2015/06/24 PHP
php自定义扩展名获取函数示例
2016/12/12 PHP
JavaScript 新手24条实用建议[TUTS+]
2009/06/21 Javascript
Javascript实现页面跳转的几种方式分享
2013/10/26 Javascript
json的使用小结
2016/06/08 Javascript
javascript使用btoa和atob来进行Base64转码和解码
2017/03/20 Javascript
HTML5开发Kinect体感游戏的实例应用
2017/09/18 Javascript
微信小程序数字滚动插件使用详解
2018/02/02 Javascript
JS实现的tab切换并显示相应内容模块功能示例
2019/08/03 Javascript
JavaScript实现PC端横向轮播图
2020/02/07 Javascript
Element Dropdown下拉菜单的使用方法
2020/07/26 Javascript
js实现手表表盘时钟与圆周运动
2020/09/18 Javascript
python实现端口转发器的方法
2015/03/13 Python
Python json模块使用实例
2015/04/11 Python
Python字符串拼接的几种方法整理
2017/08/02 Python
python实现抖音视频批量下载
2018/06/20 Python
Python两个字典键同值相加的几种方法
2019/03/05 Python
关于numpy中eye和identity的区别详解
2019/11/29 Python
python实现图片二值化及灰度处理方式
2019/12/07 Python
pytorch的batch normalize使用详解
2020/01/15 Python
python将unicode和str互相转化的实现
2020/05/11 Python
python 如何把docker-compose.yaml导入到数据库相关条目里
2021/01/15 Python
HTML5之SVG 2D入门11—用户交互性(动画)介绍及应用
2013/01/30 HTML / CSS
HTML5 3D衣服摇摆动画特效
2016/03/17 HTML / CSS
美国领先的户外服装与装备用品店:Moosejaw
2016/08/25 全球购物
财务会计专业毕业生自荐信
2013/10/02 职场文书
销售工作人员的自我评价分享
2013/11/10 职场文书
2015元旦晚会主持人开场白+结束语
2014/12/14 职场文书
九寨沟导游词
2015/02/02 职场文书
生日赠语
2015/06/23 职场文书
《巨人的花园》教学反思
2016/02/19 职场文书
Python道路车道线检测的实现
2021/06/27 Python
JavaScript原型链中函数和对象的理解
2022/06/16 Javascript