不会准。setTimeout只保证“至少延迟指定毫秒后执行”,不保证“正好在指定毫秒后执行”,因其回调需等待主线程空闲、当前宏任务及所有微任务执行完毕,且受浏览器最小延迟限制(如≥4ms)、后台节流(≥1000ms)及系统负载影响。

不会准。setTimeout 执行延迟一定不保证准时,它只承诺“至少延迟指定毫秒后执行”,不是“正好在指定毫秒后执行”。这种偏差不是 bug,而是 JavaScript 运行机制的必然结果。
主线程必须空闲,回调才能真正运行
setTimeout 的回调被放入宏任务队列,但只有当前调用栈清空、所有微任务(如 Promise.then)执行完毕后,事件循环才会从队列中取出它。如果此时主线程正执行一个耗时 200ms 的 for 循环,哪怕你设了 setTimeout(fn, 10),fn 也要等到那 200ms 结束才可能执行。
- 同步代码越长,延迟漂移越明显
- 大量 Promise 链会把 setTimeout 推到更后面,因为它得等所有微任务跑完
- 页面重排重绘、大型 DOM 操作也会占用主线程,间接拖慢定时器
浏览器强制加了“最小延迟”这道门槛
HTML5 规范和主流浏览器(Chrome、Firefox)都设置了最小延迟下限:
- 非嵌套或浅层嵌套:通常不低于 4ms(设 0 或 1–3ms,实际都≈4ms)
- 嵌套超过 5 层:明确限制为 ≥4ms
- 页面处于后台标签页:节流至 ≥1000ms(Chrome 等常见行为)
- 移动端或低功耗设备:可能进一步放宽至 16ms 或更高
Worker 里的 setTimeout 也不更准
Web Worker 虽然隔离了主线程,但它的 setTimeout 同样受宿主环境调度限制:
- 精度仍在 4–16ms 波动范围,无法突破浏览器统一的最小延迟 clamp
- Worker 自身若在做密集计算(如解密、排序),后续定时回调一样会被推迟
- 后台页面下,Worker 的定时器同样会被降频(不是完全不受影响)
- 它真正的优势是避免渲染阻塞,而非提高时间精度
没有亚毫秒级能力,也不存在“实时”调度
JavaScript 运行在用户态,依赖浏览器或 Node.js 的事件循环,不是操作系统级的高精度定时器:
- 不提供 setImmediate、usleep 或类似底层 API
- performance.now() 可测出真实延迟,但不能让 setTimeout 更准
- requestAnimationFrame 是帧同步方案,适合动画节奏,但不是通用精确延时工具
- 真正需要毫秒级可控时序(如音视频同步、游戏逻辑),需结合 performance.now() 动态校准 + 循环检查,而非依赖单次 setTimeout

















