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 相关文章推荐
根据分辩率调用不同的CSS.
Jan 08 Javascript
Javascript的并行运算实现代码
Nov 19 Javascript
JavaScript作用域链使用介绍
Aug 29 Javascript
用Jquery选择器计算table中的某一列某一行的合计
Aug 13 Javascript
JavaScript DOM事件(笔记)
Apr 08 Javascript
Active控件问题小结(附解决办法)
Jun 09 Javascript
jQuery实现简单的tab标签页效果
Sep 12 Javascript
JS防止网页被嵌入iframe框架的方法分析
Sep 13 Javascript
angularjs中的$eval方法详解
Apr 24 Javascript
JavaScript仿微信(电话)联系人列表滑动字母索引实例讲解(推荐)
Aug 16 Javascript
JS获取一个表单字段中多条数据并转化为json格式
Oct 17 Javascript
完美解决linux下node.js全局模块找不到的情况
May 16 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
初学者入门:细述PHP4的核心Zend
2006/09/05 PHP
自定义PHP分页函数
2006/10/09 PHP
PHP的开合式多级菜单程序
2006/10/09 PHP
CodeIgniter使用phpcms模板引擎
2013/11/12 PHP
在 Laravel 中动态隐藏 API 字段的方法
2019/10/25 PHP
javascript 常用关键字列表集合
2007/12/04 Javascript
通过JS 获取Mouse Position(鼠标坐标)的代码
2009/09/21 Javascript
js判断屏幕分辨率的代码
2013/07/16 Javascript
jQuery 获取兄弟元素的几种不错方法
2014/05/23 Javascript
js 左右悬浮对联广告代码示例
2014/12/12 Javascript
浅谈EasyUI中Treegrid节点的删除
2015/03/01 Javascript
解决canvas画布使用fillRect()时高度出现双倍效果的问题
2017/08/03 Javascript
jQuery实现鼠标移到某个对象时弹出显示层功能
2018/08/23 jQuery
详解swiper在vue中的应用(以3.0为例)
2018/09/20 Javascript
Node.js + express基本用法教程
2019/03/14 Javascript
JavaScript中判断为整数的多种方式及保留两位小数的方法
2019/09/09 Javascript
基于form-data请求格式详解
2019/10/29 Javascript
解决Antd Table组件表头不对齐的问题
2020/10/27 Javascript
原生js中运算符及流程控制示例详解
2021/01/05 Javascript
python使用sorted函数对列表进行排序的方法
2015/04/04 Python
Python工程师面试题 与Python基础语法相关
2016/01/14 Python
django foreignkey(外键)的实现
2019/07/29 Python
Django框架教程之中间件MiddleWare浅析
2019/12/29 Python
tensorflow 动态获取 BatchSzie 的大小实例
2020/06/30 Python
全网最细 Python 格式化输出用法讲解(推荐)
2021/01/18 Python
瑞典快乐袜子:Happy Socks
2018/02/16 全球购物
优秀员工自荐信范文
2013/10/05 职场文书
日本语毕业生自荐信
2014/02/01 职场文书
酒店周年庆活动方案
2014/08/21 职场文书
超市店庆活动方案
2014/08/31 职场文书
迟到检讨书
2015/01/26 职场文书
2015年预防青少年违法犯罪工作总结
2015/05/22 职场文书
厉行节约工作总结
2015/08/12 职场文书
JS监听Esc 键触发事键
2021/04/14 Javascript
MySQL系列之一 MariaDB-server安装
2021/07/02 MySQL
Nginx静态压缩和代码压缩提高访问速度详解
2022/05/30 Servers