前端面试 P038:嵌套定时器的最小延迟与调度选择
目前顯示中文(中國)原文
来源:方格前端讲面试 · 38.setTimeout最小延迟与嵌套定时器,5 分 39 秒。
回看定位:01:08 钳制演示 · 02:48 MessageChannel · 04:04 用途
4ms 不是每个 setTimeout 的固定成本
HTML 定时器算法中,相关 timer nesting level 大于 5 且请求 timeout 小于 4ms 时,会把该 timeout 调整到 4ms。它涉及定时任务的连续嵌套历史,不是源码里简单数几对括号。
课程用递归安排 setTimeout 观察到后续间隔约 4ms,适合说明钳制现象。但第几条日志看到变化还取决于最开始怎样启动计数;观察值不是调度精度保证。
let count = 0;
let previous = performance.now();
function tick() {
const now = performance.now();
console.log(count++, now - previous);
previous = now;
if (count < 10) setTimeout(tick, 0);
}
setTimeout(tick, 0);
本例用于观察,输出间隔随环境变化,不把某组毫秒数当标准答案。后台、节电状态与主线程工作也可能使延迟更长。
MessageChannel 能提供什么
port.postMessage 可触发相应消息任务,不走同一套定时器嵌套钳制,因此常用于任务调度。它仍要等待事件循环,不保证 0ms 或固定顺序胜过任意其他任务来源。
使用后按需关闭端口、清理监听;如果在一个消息回调里执行巨大同步工作,照样阻塞界面。视频将其描述为“真正零延迟”的替代,需要改为没有该定时器钳制保证的另一类异步调度。
根据目标选 API
动画帧通常用 requestAnimationFrame;延后任务可考虑 MessageChannel 或适用的调度 API;低优先级空闲工作可考虑 requestIdleCallback 并控制每次预算。它们不是互相完全等价的“快版 setTimeout”。