我们在使用定时器的时候,大家有没有发现有时候会有误差,明明我设置的1000ms,但是总感觉不准,这是对的,因为定时器他真的会有问题.
为什么会有
这个就得从js的执行机制说起了,在事件循环(EventLoop)执行机制中,异步事件(setInterval/setTimeout)会把回调函数放入消息队列(Event Queue)中,主线程的宏任务执行完毕后,依次执行消息队列中的微任务,等微任务执行完了再循环回来执行宏任务。由于消息队列中存在大量的任务,其他任务的执行时间就会造成定时器回调函数的延迟,如果不处理,就会一直叠加延迟,当运行时间久了之后,相差就会很大。
因此定时器是不能完全保证的。
循环定时器每次减去时间误差
var startTime = new Date().getTime();
var count = 0; //耗时任务
setInterval(function () {
var i = 0;
while (i++ < 100000000);
}, 0);
function handle() {
count++;
var offset = new Date().getTime() - (startTime + count * 1000);
var nextTime = 1000 - offset;
if (nextTime < 0) nextTime = 0;
setTimeout(handle, nextTime);
console.log(
count + ' --- ' + (new Date().getTime() - (startTime + count * 1000))
);
}
setTimeout(handle, 1000);