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 相关文章推荐
prototype与jquery下Ajax实现的差别
Sep 13 Javascript
使用js实现雪花飘落效果
Aug 26 Javascript
jquery事件与函数的使用介绍
Sep 29 Javascript
Javascript学习笔记之 函数篇(一) : 函数声明和函数表达式
Jun 24 Javascript
基于JavaScript实现回到页面顶部动画代码
May 24 Javascript
zTree异步加载展开第一级节点的实现方法
Sep 05 Javascript
jQuery中each方法的使用详解
Mar 18 jQuery
使用 Node.js 实现图片的动态裁切及算法实例代码详解
Sep 29 Javascript
js canvas画布实现高斯模糊效果
Nov 27 Javascript
jQuery实现购物车的总价计算和总价传值功能
Nov 28 jQuery
Vue2.0 $set()的正确使用详解
Jul 28 Javascript
js+h5 canvas实现图片验证码
Oct 11 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
在MongoDB中模拟Auto Increment的php代码
2011/03/06 PHP
php实现每天自动变换随机问候语的方法
2015/05/12 PHP
PHP中把有符号整型转换为无符号整型方法
2015/05/27 PHP
PHP 并发场景的几种解决方案
2019/06/14 PHP
基于JQuery框架的AJAX实例代码
2009/11/03 Javascript
jquery插件 autoComboBox 下拉框
2010/12/22 Javascript
JS模拟面向对象全解(一、类型及传递)
2011/07/13 Javascript
Javascript中的isNaN函数使用说明
2011/11/10 Javascript
Javascript自定义函数判断网站访问类型是PC还是移动终端
2014/01/10 Javascript
js实现日期级联效果
2014/01/23 Javascript
js实现特定位取反原理及示例
2014/06/30 Javascript
js父页面与子页面不同时显示的方法
2014/10/16 Javascript
Jquery解析Json格式数据过程代码
2014/10/17 Javascript
JS+CSS实现的竖向简洁折叠菜单效果代码
2015/10/22 Javascript
理解javascript模块化
2016/03/28 Javascript
微信小程序支付及退款流程详解
2017/11/30 Javascript
微信小程序时间选择插件使用详解
2018/12/28 Javascript
Python 用户登录验证的小例子
2013/03/06 Python
用python + openpyxl处理excel2007文档思路以及心得
2014/07/14 Python
详解Python多线程
2016/11/14 Python
深入理解python中函数传递参数是值传递还是引用传递
2017/11/07 Python
Django-Rest-Framework 权限管理源码浅析(小结)
2018/11/12 Python
python+pygame实现坦克大战
2019/09/10 Python
python虚拟环境模块venv使用及示例
2020/03/04 Python
Python定时任务APScheduler原理及实例解析
2020/05/30 Python
使用Python项目生成所有依赖包的清单方式
2020/07/13 Python
python获取系统内存占用信息的实例方法
2020/07/17 Python
python xlsxwriter模块的使用
2020/12/24 Python
css3实现小箭头各种图形效果
2020/07/08 HTML / CSS
连卡佛中国官网:Lane Crawford中文站
2018/01/27 全球购物
宝宝满月酒主持词和仪式流程
2014/03/27 职场文书
公司周年庆活动方案
2014/08/25 职场文书
论群众路线学习笔记
2014/11/06 职场文书
协议书范文
2015/01/27 职场文书
《为人民服务》教学反思
2016/02/20 职场文书
python套接字socket通信
2022/04/01 Python