为何setTimeout延时1ms比0ms先执行,输出顺序不符合预期?
setTimeout输出顺序异常原因说明
你碰到的执行顺序问题是浏览器对setTimeout的最小延时限制和JS事件循环机制共同导致的:
setTimeout(() => console.log('1'), 1) setTimeout(() => console.log('2'), 0) console.log('3')
- 首先执行同步代码:JS引擎会优先处理调用栈内的同步任务,
console.log('3')是同步执行的,所以第一个输出3,这个逻辑是确定的。 - 其次
setTimeout属于异步宏任务,你传入的延时参数不是回调的精确执行时间,仅代表浏览器最快要等多久才会把回调推入宏任务队列。等调用栈完全清空后,事件循环才会按队列的先进先出顺序执行宏任务回调。 - 核心原因是浏览器有最小
setTimeout延时限制:W3C的HTML标准规定,嵌套层级不超过5层的setTimeout最小延时为1ms,你设置0的延时会被浏览器自动修正为1ms。
这种情况下两个定时器的有效延时都是1ms,你先注册的打印1的定时器,所以计时结束后会先把打印1的回调推入队列,后推入打印2的回调,最终输出顺序就是3、1、2。
补充:如果是在部分没有实现1ms最小延时的老旧浏览器,或者Node.js环境下,也有可能出现你预期的3、2、1的输出,这属于不同运行环境的实现差异。
内容的提问来源于stack exchange,提问作者Brandon McConnell
相关产品推荐
相关产品推荐

