在js中若是打算使用setInterval进行倒数,计时等功能,每每是不许确的,由于setInterval的回调函数并非到时后当即执行,而是等系统计算资源空闲下来后才会执行.而下一次触发时间则是在setInterval回调函数执行完毕以后才开始计时,因此若是setInterval内执行的计算过于耗时,或者有其余耗时任务在执行,setInterval的计时会愈来愈不许,延迟很厉害.javascript
下面的代码能够说明这个问题java
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 ......
能够看到延迟是愈来愈严重的.blog
为了在js里可使用相对准确的计时功能,咱们能够ip
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(也就是周期时间)减去当前时间和准确时间的差距,来算出下次触发的时间,从而修正了当前触发的延迟.资源
下面是输出get
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 ......
能够看到虽然触发时间并不是绝对准确,但因为每次触发都进行及时修正,因此并无形成偏差积累.回调函数