为何两个setTimeout不在同一事件循环中?
为什么两个setTimeout回调不在同一事件循环轮次执行?
先看执行的代码:
setTimeout(() => new Promise((r) => {console.log(1);r();}).then(() => console.log('1 mic'))) setTimeout(() => new Promise((r) => {console.log(2);r();}).then(() => console.log('2 mic')))
执行后输出顺序是:
1 1 mic 2 2 mic
核心原因:事件循环的"宏任务+微任务"处理规则
JavaScript的事件循环是按轮次处理任务的,每一轮的固定执行流程是:
- 从宏任务队列取出第一个任务执行
- 执行完这个宏任务后,立刻清空当前所有微任务队列里的任务
- 微任务全部执行完毕,这一轮事件循环结束,再开启下一轮,取下一个宏任务
回到你的代码:
- 两个
setTimeout的回调都属于宏任务,因为没传延迟参数(默认延迟0),会按代码书写顺序依次加入宏任务队列。 - 第一轮事件循环:取出第一个
setTimeout回调执行——先同步打印1,然后Promise的resolve触发,把then里的回调加入微任务队列。 - 第一个宏任务执行完毕,立刻处理所有微任务,执行
then回调打印1 mic,第一轮事件循环结束。 - 第二轮事件循环:取出第二个
setTimeout回调执行——同步打印2,同样触发Promise的then回调加入微任务队列。 - 第二个宏任务执行完毕,处理微任务打印
2 mic,第二轮事件循环结束。
简单总结:每一轮事件循环只处理一个宏任务,处理完宏任务必须清空所有微任务才会开启下一轮,所以两个setTimeout的回调会分属不同的事件循环轮次执行。
内容的提问来源于stack exchange,提问作者user21004055
相关产品推荐
相关产品推荐

