最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
如何通过 浏览器事件循环 (Event Loop) 机制来阐明 setTimeout(0) 为何不准时
时间:2026-06-06 10:14:53 编辑:袖梨 来源:一聚教程网
setTimeout(0)不是立刻执行,而是进入下一轮宏任务队列,需等待当前宏任务及所有微任务执行完毕后才调度;受浏览器最小延迟(≥4ms)、后台节流(可达1000ms)等限制,实际延迟常为5–15ms或更高。
setTimeout(0) 不是“立刻执行”,而是“尽快在下一个宏任务阶段执行”——它必须等完当前宏任务 + 所有微任务,才能排队等待调度。
它不等于同步执行
很多人以为 setTimeout(0) 能绕过异步队列、实现“马上运行”,其实它只是把回调函数放进「下一轮 timers 阶段」的任务队列头部。但这个队列不会被立即处理,必须满足两个前提:
- 当前正在执行的宏任务(比如点击事件处理函数、脚本加载后的顶层代码)已全部结束
- 所有已排队的微任务(Promise.then、queueMicrotask、MutationObserver 回调等)已被清空
微任务会明显拖慢它的时机
即使主线程很快空闲,微任务也会抢占 setTimeout(0) 的执行机会。例如:
console.log('1');setTimeout(() => console.log('2'), 0);Promise.resolve().then(() => console.log('3'));console.log('4');// 输出顺序:1 → 4 → 3 → 2
这里 Promise.then 在当前宏任务末尾立即执行,而 setTimeout(0) 的回调要等到下一轮事件循环的 timers 阶段才被取出——中间还可能插入其他宏任务(如用户点击、IO 回调)。
浏览器还有最小延迟限制
根据 HTML 规范,嵌套调用超过 5 层的 setTimeout,浏览器会强制将延迟设为至少 4ms。也就是说,即使你写的是 setTimeout(fn, 0),实际入队时间也可能被拉长到 4ms 之后,再叠加任务排队耗时,整体延迟常达 5–15ms 甚至更高。
后台标签页还会进一步节流
当页面处于非激活状态(比如切换到其他浏览器标签),Chrome 等主流浏览器会把定时器最小间隔提升至 1000ms。此时 setTimeout(0) 可能等上整整 1 秒才触发,完全失去“快速响应”的意义。
相关文章
- 精选大数据分析软件推荐 方便易用的大数据分析软件集合 06-16
- 讯飞星火开发者注册登录教程:3种认证方式与6项配置检查 06-16
- 免费缓存电视剧的app合集 受欢迎的电视剧app前五 06-16
- 热门的短视频app有哪些 值得推荐的短视频app合集 06-16
- win11怎么关闭休眠功能 win11删除休眠文件命令清理 06-16
- 图片编辑软件有哪些 好用的图片编辑软件推荐 06-16