setTimeout 定时器不准,意味着,你设置的定时任务 比如 1s 后执行,可能晚于 1s 后才执行。注意,不会提前于 1s 执行哦。
不准的原因是,setTimeout 是一个异步任务,在执行到 setTimeout 的时候,js 引擎不会立刻把定时任务放到事件循环的任务队列中,而是等待时间到了,再放进事件循环的队列中。
注意,是时间到了才加入队列,那么如果队列中已经有了其他的任务要执行,这个新加的定时器任务自然要等待前面的任务结束,所以时间会延后。
我们只能尽量调整延后的时间偏差,不能修正到完全精确,代码如下
- // performance.now 比 Date.now 更精确
- let startTime = performance.now();
- // count表示定时器被调用的次数,次数需要是全局变量
- let count = 0
- function myTimeout(){
- let runTime = performance.now();
- // 先增加次数
- ++count;
- // diffTime 就是已经延后的时间
- let diffTime = (runTime - (startTime + count * 1000));
- // 既然已经延后了,就需要时间间隔,减去已经拖延的时间,提前开始
- setTimeout(myTimeout, 1000 - diffTime);
- }
- let t = setTimeout(myTimeout , 1000);