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引擎在同步代码执行完后,会持续处理微任务队列直到为空,处理过程中新生成的微任务会被追加到队列末尾:
- 执行第一个微任务:
console.log(1),输出1。该回调返回undefined,触发第二个.then(()=>console.log(2))的回调加入队列。 - 执行第二个微任务:
console.log(2),输出2。该回调返回undefined,触发第三个.then(()=>console.log(3))的回调加入队列。 - 执行第三个微任务:async函数中
await后续的代码,输出33 'outside'。随后执行await Promise.resolve(10),将console.log(10)包装成新的微任务加入队列。 - 执行第四个微任务:
console.log(3),输出3。 - 执行第五个微任务:
console.log(10),输出10。
为什么33 'outside'会延迟?
核心原因是await的微任务调度规则:
- 当
await一个已完成的Promise时,后续代码不会同步执行,而是会被包装成微任务回调。 - 这个回调的执行时机晚于当前已排队的同级微任务(比如全局链式Promise的前两个
then回调),但会优先于后续在微任务处理过程中新生成的微任务(比如全局链式Promise的第三个then回调)。 - 简单来说,
await会让后续代码“插队”到当前链式Promise的中间执行,但不会打断已排队的微任务顺序,因此33 'outside'会在1、2之后,3之前输出。
内容的提问来源于stack exchange,提问作者reddur
相关产品推荐
相关产品推荐

