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

JavaScript中Promise队列处理机制及代码执行顺序疑问

JavaScript Promise执行流程解析:给定代码的输出顺序说明

代码与输出回顾

const promisePrint = (n) =>{
    return new Promise(res=>{
        console.log(n, 'inside')
        res(n)
    })
}

(async()=>{
    console.log(await promisePrint(33), 'outside')
    console.log(await Promise.resolve(10))
})()

Promise.resolve()
.then(()=>console.log(1))
.then(()=>console.log(2))
.then(()=>console.log(3))

输出结果:

33 'inside'
1
2
33 'outside'
3
10

执行步骤拆解

1. 同步代码执行阶段

  • 声明promisePrint函数,无输出。
  • 执行立即调用的async函数:
    • 调用promisePrint(33):创建Promise时,executor函数是同步执行的,直接输出 33 'inside',并立即resolve该Promise。
    • 遇到await:此时Promise已完成,但await会将async函数中后续的代码(console.log(33, 'outside')及之后的代码)包装成微任务回调,随后暂停async函数,跳出到全局代码。
  • 执行全局链式Promise:Promise.resolve()立即完成,第一个.then(()=>console.log(1))的回调被加入微任务队列。

2. 微任务队列处理阶段

JavaScript引擎在同步代码执行完后,会持续处理微任务队列直到为空,处理过程中新生成的微任务会被追加到队列末尾:

  1. 执行第一个微任务:console.log(1),输出 1。该回调返回undefined,触发第二个.then(()=>console.log(2))的回调加入队列。
  2. 执行第二个微任务:console.log(2),输出 2。该回调返回undefined,触发第三个.then(()=>console.log(3))的回调加入队列。
  3. 执行第三个微任务:async函数中await后续的代码,输出 33 'outside'。随后执行await Promise.resolve(10),将console.log(10)包装成新的微任务加入队列。
  4. 执行第四个微任务:console.log(3),输出 3。
  5. 执行第五个微任务:console.log(10),输出 10。

为什么33 'outside'会延迟?

核心原因是await的微任务调度规则:

  • 当await一个已完成的Promise时,后续代码不会同步执行,而是会被包装成微任务回调。
  • 这个回调的执行时机晚于当前已排队的同级微任务(比如全局链式Promise的前两个then回调),但会优先于后续在微任务处理过程中新生成的微任务(比如全局链式Promise的第三个then回调)。
  • 简单来说,await会让后续代码“插队”到当前链式Promise的中间执行,但不会打断已排队的微任务顺序,因此33 'outside'会在1、2之后,3之前输出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 11:36:06