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 将disabled的元素置为enabled的三种方法
Jul 25 Javascript
js弹出层永远居中实现思路及代码
Nov 29 Javascript
jQuery中:contains选择器用法实例
Dec 30 Javascript
JS实现统计复选框选中个数并提示确定与取消的方法
Jul 01 Javascript
JS实现鼠标滑过链接改变网页背景颜色的方法
Oct 20 Javascript
前端js实现文件的断点续传 后端PHP文件接收
Oct 14 Javascript
BootStrap注意事项小结(五)表单
Mar 10 Javascript
深入理解Vue 单向数据流的原理
Nov 09 Javascript
JavaScript中将值转换为字符串的五种方法总结
Jun 06 Javascript
vue中defineProperty和Proxy的区别详解
Nov 30 Vue.js
测量JavaScript函数的性能各种方式对比
Apr 27 Javascript
JavaScript实现简单计时器
Jun 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
PHP实现自动登入google play下载app report的方法
2014/09/23 PHP
高质量PHP代码的50个实用技巧必备(上)
2016/01/22 PHP
javascript避免数字计算精度误差的方法详解
2014/03/05 Javascript
js 通过html()及text()方法获取并设置p标签的显示值
2014/05/14 Javascript
详谈jQuery中的this和$(this)
2014/11/13 Javascript
jQuery中animate()的使用方法及解决$(”body“).animate({“scrollTop”:top})不被Firefox支持的问题
2017/04/04 jQuery
JavaSctit 利用FileReader和滤镜上传图片预览功能
2017/09/05 Javascript
Vue+SpringBoot开发V部落博客管理平台
2017/12/27 Javascript
vue-cli webpack2项目打包优化分享
2018/02/07 Javascript
JavaScript门道之标准库
2018/05/26 Javascript
jQuery实现参数自定义的文字跑马灯效果
2018/08/15 jQuery
webpack多入口多出口的实现方法
2018/08/17 Javascript
详解Ant Design of React的安装和使用方法
2018/12/27 Javascript
浅谈Angular单元测试总结
2019/03/22 Javascript
koa router 多文件引入的方法示例
2019/05/22 Javascript
JS实现拖动模糊框特效
2020/08/25 Javascript
[01:00:52]2018DOTA2亚洲邀请赛 4.4 淘汰赛 EG vs LGD 第一场
2018/04/05 DOTA
python实现比较两段文本不同之处的方法
2015/05/30 Python
图文讲解选择排序算法的原理及在Python中的实现
2016/05/04 Python
Python网络编程使用select实现socket全双工异步通信功能示例
2018/04/09 Python
Random 在 Python 中的使用方法
2018/08/09 Python
python覆盖写入,追加写入的实例
2019/06/26 Python
jupyter notebook中美观显示矩阵实例
2020/04/17 Python
Python判断变量是否是None写法代码实例
2020/10/09 Python
台湾生鲜宅配:大口市集
2017/10/14 全球购物
UNIX命令速查表
2012/03/10 面试题
艺术系应届生的自我评价
2013/10/19 职场文书
给学校的建议书范文
2014/05/15 职场文书
篮球赛口号
2014/06/18 职场文书
党委班子对照检查材料
2014/08/19 职场文书
个人专业技术总结
2015/03/05 职场文书
护士心得体会范文
2016/01/25 职场文书
七年级作文之环保作文
2019/10/17 职场文书
Java基础之线程锁相关知识总结
2021/06/30 Java/Android
Windows Server 2019 配置远程控制以及管理方法
2022/04/28 Servers
python缺失值填充方法示例代码
2022/12/24 Python