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

Event Loop、微/宏任务队列理解困惑及代码执行顺序疑问

理解Event Loop与代码执行顺序问题

核心误解点

你之前的预期错误,根源在于Promise构造函数的回调是同步执行的,并非异步任务。很多人会误以为Promise相关代码都是异步,但实际上只有then/catch/finally以及await后续的代码才会进入微任务队列,而Promise构造函数本身是在主线程同步流程里执行的。

代码逐行执行流程(可视化Event Loop)

我们一步步拆解代码的执行顺序,对应Event Loop的各个阶段:

1. 主线程同步执行阶段

  • 执行console.log(1) → 输出 1
  • 执行const wait2sec = new Promise(...):
    • 立刻执行Promise构造函数内的同步代码:
      • console.log(2) → 输出 2
      • 调用setTimeout(...):将这个回调函数加入宏任务队列(等待2秒后才会被推入执行队列)
      • console.log(4) → 输出 4
    • 此时wait2sec是一个处于pending状态的Promise对象
  • 定义异步函数X,随后调用X():
    • 进入X函数,执行到await wait2sec:
      • 由于wait2sec当前是pending状态,引擎会将X函数中await之后的代码(console.log('ok'))注册为wait2sec的then回调(属于微任务,但需等待wait2sec变为fulfilled才会进入微任务队列)
      • 暂停X函数的执行,主线程跳出X函数,继续执行后续同步代码
  • 执行console.log(5) → 输出 5
  • 此时主线程的同步代码全部执行完毕,开始处理任务队列

2. 任务队列处理阶段

  • 首先检查微任务队列:此时wait2sec仍为pending,没有可执行的微任务,主线程进入等待状态
  • 2秒后,setTimeout的回调被推入宏任务队列,主线程开始执行这个宏任务:
    • console.log(3) → 输出 3
    • 调用resolve(true):将wait2sec的状态改为fulfilled,同时将之前注册的then回调(console.log('ok'))加入微任务队列
  • 当前宏任务执行完毕,主线程再次检查微任务队列,发现有可执行任务:
    • 执行console.log('ok') → 输出 ok

最终输出顺序验证

按照上述流程,实际输出顺序为:1 → 2 → 4 → 5 → 3 → ok,和你看到的结果一致。

关键知识点总结

  • 同步代码:优先在主线程执行,执行完毕后才会处理任务队列
  • Promise构造函数:内部的回调是同步执行的,只有then/catch/finally回调才属于微任务
  • 宏任务:包括setTimeout、setInterval、I/O操作等,执行优先级低于微任务
  • 微任务:包括Promise的then/catch/finally、await后续代码、process.nextTick(Node.js)等,每次宏任务执行完毕后,会先清空所有微任务队列才会执行下一个宏任务

内容的提问来源于stack exchange,提问作者Ahmed Hassan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 06:25:06