JavaScript异步函数(Promise)执行顺序及Microtask Queue分步解析问询
Let's walk through exactly why your code outputs 9,1,4,2,5,8,3,6,7, focusing on how microtasks work in the event loop.
Core Background
- Synchronous code runs first, top to bottom.
- Microtasks (like Promise
.then()callbacks) are queued and executed immediately after synchronous code finishes, before any macro tasks (e.g.,setTimeout). - Microtasks are processed in FIFO order, and any new microtasks added during execution are added to the end of the queue and processed next.
Step 1: Run All Synchronous Code
var promise = Promise.resolve();→ Creates a resolved Promise (let's call it P0).promise = promise.then(Callback A);→ Attach Callback A to P0. Since P0 is resolved, Callback A goes straight to the microtask queue. Thepromisevariable now points to a new pending Promise (P1).promise = promise.then(Callback B);→ Attach Callback B to P1. P1 is pending, so Callback B isn't queued yet.promisenow points to another pending Promise (P2).console.log('9');→ Outputs9right away.
Microtask Queue now: [Callback A]
Step 2: Process First Microtask (Callback A)
Execute Callback A:
console.log('1');→ Outputs1.var promise2 = Promise.resolve();→ Creates resolved Promise P3.promise2 = promise2.then(Callback C);→ Attach Callback C to P3. P3 is resolved, so Callback C is added to the microtask queue.promise2now points to pending Promise P4.promise2 = promise2.then(Callback D);→ Attach Callback D to P4. P4 is pending, so Callback D stays waiting for P4 to resolve.console.log('4');→ Outputs4.
After Callback A finishes, P1 resolves → Callback B is added to the microtask queue.
Microtask Queue now: [Callback C, Callback B]
Step3: Process Callback C
Execute Callback C:
console.log('2');→ Outputs2.
This resolves P4 → Callback D is added to the microtask queue.
Microtask Queue now: [Callback B, Callback D]
Step4: Process Callback B
Execute Callback B:
console.log('5');→ Outputs5.var promise2 = Promise.resolve();→ Creates resolved Promise P6.promise2 = promise2.then(Callback E);→ Attach Callback E to P6. P6 is resolved, so Callback E goes to the microtask queue.promise2now points to pending Promise P7.promise2 = promise2.then(Callback F);→ Attach Callback F to P7. P7 is pending, so Callback F waits.console.log('8');→ Outputs8.
Microtask Queue now: [Callback D, Callback E]
Step5: Process Callback D
Execute Callback D:
console.log('3');→ Outputs3.
Microtask Queue now: [Callback E]
Step6: Process Callback E
Execute Callback E:
console.log('6');→ Outputs6.
This resolves P7 → Callback F is added to the microtask queue.
Microtask Queue now: [Callback F]
Step7: Process Callback F
Execute Callback F:
console.log('7');→ Outputs7.
No more tasks left in the queue.
Final Output Sequence
Putting it all together, the order is: 9,1,4,2,5,8,3,6,7
内容的提问来源于stack exchange,提问作者Won Jin Kim

