JavaScript微任务执行顺序疑问:为何输出是2、1而非1、2?
解惑:为何Event Loop下输出顺序是2、1而非1、2
你的推理核心错误在于:async函数返回Promise时,其状态的settle是通过微任务完成的,而非同步,这导致console.log(1)的回调加入微队列的时机晚于console.log(2)的回调。
完整执行流程拆解
1. 同步代码执行阶段
- 首先执行
f1():- 进入
f1函数,调用f2() - 进入
f2函数,执行return new Promise(resolve => resolve()):- 创建Promise实例P2,executor函数同步执行
resolve(),P2立即变为resolved状态 - 由于
f2是async函数,它返回的Promise实例P1,会通过内部微任务同步P2的状态——即使P2已经resolved,这个同步过程也不会立刻完成,必须等当前同步代码执行结束后才会处理这个内部微任务 - 此时给P1绑定
then(() => console.log(1)),但因为P1还未变为resolved,这个回调暂时不会进入微队列
- 创建Promise实例P2,executor函数同步执行
- 进入
- 同步代码继续执行
Promise.resolve().then(() => console.log(2)):Promise.resolve()返回已resolved的Promise实例P3- 给P3绑定的then回调会立即被加入当前微任务队列(因为P3状态已确定)
2. 微任务队列执行阶段
- 同步代码执行完毕,调用栈为空,开始处理微队列:
- 第一个任务是
console.log(2)的回调,执行后输出2 - 微队列处理完当前任务后,检查新加入的微任务:此时async函数f2返回的P1的内部同步微任务执行,P1变为resolved状态,绑定的
console.log(1)回调被加入微队列 - 执行这个新的微任务,输出
1
- 第一个任务是
关键误区纠正
你之前误以为f2()返回的Promise会同步变为resolved,导致其then回调直接进入微队列,但实际上async函数对返回的Promise的状态同步是通过微任务实现的,这就导致console.log(1)的回调比console.log(2)的回调晚一步进入微队列,最终输出顺序为2、1。
内容的提问来源于stack exchange,提问作者Party Favor
相关产品推荐
相关产品推荐

