先追這段程式
先放 start,排入 Promise 回呼和 queueMicrotask,然後同步放 end。最後再排一個回呼印出記錄。
const trace=['start'];
Promise.resolve().then(()=>trace.push('promise'));
queueMicrotask(()=>trace.push('microtask'));
trace.push('end');
Promise.resolve().then(()=>console.log(JSON.stringify(trace)));
["start","end","promise","microtask"]| 執行位置 | 加入值 | 當時記錄 |
|---|---|---|
| 同步程式 | start, end | ["start","end"] |
| 首個排隊回呼 | promise | ["start","end","promise"] |
| 明確微任務 | microtask | ["start","end","promise","microtask"] |
結果為何如此
這段同步程式會先跑完;本例 Promise 回呼先入隊,明確微任務隨後,列印回呼最後。不涉及實際毫秒,也不推論其他工作或不同執行環境的整體排程。
比較另一種寫法
Promise 已 fulfilled,也不會在 .then 當下同步執行。即時讀旗標是假,後面的回呼才讀到真。
let ran=false;Promise.resolve().then(()=>{ran=true;});const immediate=ran;
Promise.resolve().then(()=>console.log(JSON.stringify({immediate,later:ran})));
{"immediate":false,"later":true}試清邊界
先排 queueMicrotask,再排 Promise 回呼,次序怎樣變?
查看參考答案
兩個排隊標記調換;本程式的 start、end 仍先於它們。
const trace=['start'];queueMicrotask(()=>trace.push('microtask'));Promise.resolve().then(()=>trace.push('promise'));trace.push('end');
Promise.resolve().then(()=>console.log(JSON.stringify(trace)));
["start","end","microtask","promise"]