在日常工作中,时常会有实现一个计时器的需求,然而直接简单的使用setTimeout和setInterval,会有一定的误差造成计时不准。
原因
1、虽然js有事件循环机制实现了异步,但由于js依然是单线程的,无法保证setTimeout和setInterval在准确的时间点去执行回调函数,且计时会在回调函数执行结束之后才开始。
2、在谷歌浏览器中,若当前tab页面不处于焦点状态,则由于浏览器的性能优化机制,会把setTimeout和setInterval做一个优化,降低他们的性能。
解决办法
解决原因1: 记录获取当前时间戳,通过计算获取的时间戳差值来显示计时器的数值,这样保证了时间的正确。
解决原因2: 使用webworker去实现,在浏览器另开一个线程,不受浏览器优化影响。
示例代码:
const code = 'setInterval(() => postMessage(1), 10);';
workerRef.current = new Worker(URL.createObjectURL(new Blob([code])));
workerRef.current.onmessage = ({ data: count }) => {if (count === 1) {//接收到消息进行时间处理handleTimeText();}
};