定时器
setTimeout 与 setInterval 有什么区别?
setTimeout(callback, delay?, ...args): 延迟delay毫秒后执行一次, 返回定时器 ID;setInterval(callback, delay?, ...args): 每间隔delay毫秒重复执行, 返回定时器 ID;- 取消: 分别用
clearTimeout(id)与clearInterval(id); - 执行归属: 回调作为宏任务入队, 具体时机见 单线程与事件循环;
定时器有哪些精度与调度局限?
- 精度: 时间精度无法保证, 通常有约 6ms 偏差;
- 累积误差:
setTimeout的每次回调都会叠加前一次的耗时; - 任务跳过:
setInterval在上一次回调未执行完时可能跳过或叠加; - 规避: 需要严格间隔时用
setTimeout递归调度代替setInterval;
如何用两者互相模拟?
setTimeout实现setInterval: 每次回调结束后再排下一次, 避免累积误差;
function mySetInterval(fn, delay) {
let timer = null;
const interval = () => {
fn();
timer = setTimeout(interval, delay);
};
timer = setTimeout(interval, delay);
return { cancel: () => clearTimeout(timer) };
}
setInterval实现setTimeout: 第一次触发时先清除自身再执行回调;
function mySetTimeout(fn, time) {
const timer = setInterval(() => {
clearInterval(timer);
fn();
}, time);
return { cancel: () => clearInterval(timer) };
}