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代码)
Oct 29 Javascript
js跨域访问示例(客户端/服务端)
May 19 Javascript
Javascript中数组方法汇总(推荐)
Apr 01 Javascript
javascript嵌套函数和在函数内调用外部函数的区别分析
Jan 31 Javascript
Ubuntu系统下Angularjs开发环境安装
Sep 01 Javascript
Node连接mysql数据库方法介绍
Feb 07 Javascript
详解Vue学习笔记入门篇之组件的内容分发(slot)
Jul 17 Javascript
详解JS中的this、apply、call、bind(经典面试题)
Sep 19 Javascript
BootStrap TreeView使用实例详解
Nov 01 Javascript
QML实现圆环颜色选择器
Sep 25 Javascript
js 下拉菜单点击旁边收起实现(踩坑记)
Sep 29 Javascript
JavaScript 判断数据类型的4种方法
Sep 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
dede全站URL静态化改造[070414更正]
2007/04/17 PHP
在PHP中利用wsdl创建标准webservice的实现代码
2011/12/07 PHP
codeigniter中实现一次性加载多个view的方法
2015/03/20 PHP
Yii列表定义与使用分页方法小结(3种方法)
2016/07/15 PHP
jQuery Ajax 仿AjaxPro.Utility.RegisterTypeForAjax辅助方法
2011/09/27 Javascript
分享9个最好用的JavaScript开发工具和代码编辑器
2015/03/24 Javascript
jQuery xml字符串的解析、读取及查找方法
2016/03/01 Javascript
jQuery 常用代码集锦(必看篇)
2016/05/16 Javascript
jQuery自定义插件详解及实例代码
2016/12/29 Javascript
jQuery插件HighCharts实现的2D条状图效果示例【附demo源码下载】
2017/03/15 Javascript
es7学习教程之fetch解决异步嵌套问题的方法示例
2017/07/21 Javascript
JS跳转手机站url的若干注意事项
2017/10/18 Javascript
微信小程序-getUserInfo回调的实例详解
2017/10/27 Javascript
angularJs 表格添加删除修改查询方法
2018/02/27 Javascript
[08:40]Navi Vs Newbee
2018/06/07 DOTA
python通过openpyxl生成Excel文件的方法
2015/05/12 Python
python返回昨天日期的方法
2015/05/13 Python
python实现支持目录FTP上传下载文件的方法
2015/06/03 Python
python3实现抓取网页资源的 N 种方法
2017/05/02 Python
python遍历文件夹下所有excel文件
2018/01/03 Python
Python pandas自定义函数的使用方法示例
2019/11/20 Python
Python中有几个关键字
2020/06/04 Python
Python文件夹批处理操作代码实例
2020/07/21 Python
python 代码运行时间获取方式详解
2020/09/18 Python
使用CSS3制作一个简单的Chrome模拟器
2015/07/15 HTML / CSS
Mountain Warehouse波兰官方网站:英国户外品牌
2019/08/29 全球购物
声明struct x1 { . . . }; 和typedef struct { . . . }x2;有什么不同
2012/06/02 面试题
XML文档面试题
2015/08/05 面试题
假日旅行社实习自我鉴定
2013/09/24 职场文书
旅游与酒店管理的自我评价分享
2013/11/03 职场文书
成功经营餐厅的创业计划书范文
2013/12/26 职场文书
2014教师党员个人自我评议
2014/09/20 职场文书
公司表扬信格式
2015/05/04 职场文书
2015年政治教研组工作总结
2015/07/22 职场文书
Python Django 后台管理之后台模型属性详解
2021/04/25 Python
告别网页搜索!教你用python实现一款属于自己的翻译词典软件
2021/06/03 Python