解决setInterval计时器不准的问题

在js中如果打算使用setInterval进行倒数,计时等功能,往往是不准确的,因为setInterval的回调函数并不是到时后立即执行,而是等系统计算资源空闲下来后才会执行.而下一次触发时间则是在setInterval回调函数执行完毕之后才开始计时,所以如果setInterval内执行的计算过于耗时,或者有其他耗时任务在执行,setInterval的计时会越来越不准,延迟很厉害.

下面的代码可以说明这个问题

?





1

2

3

4

5

6

7

8

9

10

11

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触发时间和应该正确触发时间的延迟毫秒数

?





1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

176

340

495

652

807

961

1114

1268

1425

1579

1734

1888

2048

2201

2357

2521

2679

2834

2996

......

可以看到延迟是越来越严重的.

为了在js里可以使用相对准确的计时功能,我们可以

?





1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

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(也就是周期时间)减去当前时间和准确时间的差距,来算出下次触发的时间,从而修正了当前触发的延迟.

下面是输出

?





1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

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

......

可以看到虽然触发时间并非绝对准确,但由于每次触发都进行及时修正,所以并没有造成误差积累.

时间: 2024-10-16 21:20:14

解决setInterval计时器不准的问题的相关文章

setInterval计时器延时问题

计时器延时问题 js计时器 使用setTimeout.setInterval函数时,第二个参数的设置的时间间隔t是自该函数(setTimeout(f1,t).setInterval(f1,t))被调用时起,经过t毫秒后,f1被加入UI任务队列,但不一定执行,尤其是在期间有其他任务执行时,所以可能会有时间延时.因此使用setInterval函数制作计时器时,会出现延时. var startTime = new Date().getTime(); var count = 0; /*setInterv

setInterval 计时器

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html> <head> <title> New Document </title> <meta name="Generator" content="EditPlus&

javaScript知识体系(中)- DOM、BOM、其它内置对象

1. DOM基本概念 1.1 DOM DOM Document Object Model 文档对象模型     就是把HTML文档模型化,当作对象来处理     DOM提供的一系列属性和方法可以视作一个工具箱,极大地方便了我们对文档的处理. 1.2 内容概念 文档(Document):就是指HTML或者XML文件     节点(Node):HTML文档中的所有内容都可以称之为节点,常见的节点有         元素节点 属性节点 文本节点 注释节点     元素(Element)        

Javascript 多物体运动的实现

这篇文章主要介绍了Javascript 多物体运动的实现,需要的朋友可以参考下 我们先来看下之前的运动的代码,是否支持多物体运动,会出现怎么样的问题. 代码如下: 1 <style type="text/css"> 2 div { 3 width: 100px; 4 height: 50px; 5 background: red; 6 margin: 10px; 7 } 8 </style> 代码如下: 1 <body> 2 <div>&

Node.js 打造实时多人游戏框架

在 Node.js 如火如荼发展的今天,我们已经可以用它来做各种各样的事情.前段时间UP主参加了极客松活动,在这次活动中我们意在做出一款让“低头族”能够更多交流的游戏,核心功能便是 Lan Party 概念的实时多人互动.极客松比赛只有短得可怜的36个小时,要求一切都敏捷迅速.在这样的前提下初期的准备显得有些“水到渠成”.跨平台应用的 solution 我们选择了node-webkit,它足够简单且符合我们的要求. 按照需求,我们的开发可以按照模块分开进行.本文具体讲述了开发 Spaceroom

深入理解滚动scroll

原文链接:http://www.cnblogs.com/xiaohuochai/p/5831640.html#undefined 滚动宽高 scrollHeight scrollHeight表示元素的总高度,包括由于溢出而无法展示在网页的不可见部分 scrollWidth scrollWidth表示元素的总宽度,包括由于溢出而无法展示在网页的不可见部分 [注意]IE7-浏览器返回值是不准确的 [1]没有滚动条时,scrollHeight与clientHeight属性结果相等,scrollWidt

JavaScript进阶 - 第8章 浏览器对象

第8章 浏览器对象 8-1 window对象 window对象是BOM的核心,window对象指当前的浏览器窗口. window对象方法: 注意:在JavaScript基础篇中,已讲解了部分属性,window对象重点讲解计时器. 任务 在右边编辑器script标签内补充代码,弹出对话框"欢迎来到慕课网". 定义一个函数,实现打开一个网页,宽为600,高为400. 当点击"点击我,打开新窗口"按钮时,在打开网页. 如果忘记了,可以查看JavaScript基础篇. 代码

javascript 高级技巧详解

函数的使用技巧 javascript内置的类型检测机制并非完全可靠.在Object.prototype.toString()方法没有被修改的前提下,可以使用下面的安全检测方法检测是不是原生的: function isArray(value){ return Object.prototype.toString.call(value)=="[object Array]"; } function isFunction(value){ return Object.prototype.toStr

javascript 学习总结第二天

  javascript 学习总结第二天 函数和对象 对象 声明方式 newObject() {} 构造函数 元素的操作 . [] this 对象的遍历 for in with简便操作 函数 函数的声明方式 functiondemo(){} var demo= function(){} var demo= new Function('x','y','alert(x+y)'); 函数的调用 在代码中直接调用 事件触发 赋值给一个变量 注意事项 优先级 在js中定义变量的时候不能跟函数名冲突否则会覆