You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 00:56:21