async function async1() { console.log("async1 start"); await async2(); console.log("async1 end"); } async function async2() { console.log("async2"); } console.log("script start"); setTimeout(function () { console.log("setTimeout"); }, 0); async1(); new Promise(function (resolve) { console.log("promise1"); resolve(); }).then(function () { console.log("promise2"); }); console.log("script end");
解析:javascript
async function async1() { console.log("async1 start"); // 六、控制檯打印 async1 start await async2(); // 七、先執行 async2 // 八、下面的代碼須要等待返回正確的 Promise 後才執行(異步|微任務)(添加微任務1) console.log("async1 end"); // 1五、執行微任務1 控制檯打印 async1 end } // 一、建立一個 async1 函數 async function async2() { console.log("async2"); // 九、控制檯打印 async2 } // 二、建立一個 async2 函數 console.log("script start"); // 三、控制檯打印 script start setTimeout(function () { console.log("setTimeout"); // 1七、控制檯輸出 setTimeout }, 0); // 四、設置一個定時器 (添加宏任務1) async1(); // 五、執行 async1 new Promise(function (resolve) { console.log("promise1"); // 十一、控制檯打印 promise1 resolve(); // 十二、添加微任務2 }).then(function () { console.log("promise2"); // 1六、執行微任務2 控制檯打印 promise2 }); // 十、當即執行 new Promise console.log("script end"); // 1三、控制檯打印 script end // 1四、清空微任務 // 1五、執行一個宏任務 // script start // async1 start // async2 // promise1 // script end // async1 end // promise2 // setTimeout
總結:java
process.nextTick
,promise
,MutationObserver
,其中 process.nextTick
爲 Node 獨有。script
, setTimeout
,setInterval
,setImmediate
,I/O
,UI rendering
。這裏不少人會有個誤區,認爲微任務快於宏任務,實際上是錯誤的。由於宏任務中包括了 script
,瀏覽器會先執行一個宏任務,接下來有異步代碼的話纔會先執行微任務。面試
console.log(1); setTimeout((_) => { console.log(2); }, 1000); async function fn() { console.log(3); setTimeout((_) => { console.log(4); }, 20); return Promise.reject(); } async function run() { console.log(5); await fn(); console.log(6); } run(); // 須要執行150MS左右 for (let i = 0; i < 90000000; i++) {} setTimeout((_) => { console.log(7); new Promise((resolve) => { console.log(8); resolve(); }).then((_) => { console.log(9); }); }, 0); console.log(10);
解析編程
console.log(1); // 一、輸出 1 setTimeout((_) => { console.log(2); // 2二、輸出 2 }, 1000); // 二、添加 宏任務1 async function fn() { console.log(3); // 八、輸出 3 setTimeout((_) => { console.log(4); // 輸出 4 }, 20); // 九、添加一個 宏任務2 return Promise.reject(); } // 三、初始化函數fn async function run() { console.log(5); // 六、輸出 5 await fn(); // 七、執行fn // 八、添加一個 微任務1 console.log(6); // 1三、上面返回的失敗狀態,因此上面代碼不執行 } // 四、初始化函數 run run(); // 五、執行run函數 // 須要執行150MS左右 for (let i = 0; i < 90000000; i++) {} // 九、執行循環 150ms (以前設置的定時器到時候,可是要繼續把同步任務執行完) setTimeout((_) => { console.log(7); // 1六、輸出 7 new Promise((resolve) => { console.log(8); // 1七、執行promise 輸出 8 // 1八、添加一個微任務2 resolve(); }).then((_) => { console.log(9); // 20、輸出 9 }); }, 0); // 十、添加一個 宏任務3 console.log(10); // 十一、輸出 10 // 十二、執行一隊微任務 執行微任務1 // 1四、執行一個宏任務 找到最須要執行的宏任務(定時器到時) 執行宏任務2 // 1五、沒有微任務 再執行一個宏任務(定時器到時) 執行宏任務3 // 1九、執行一隊微任務 執行微任務2 // 2一、執行一個宏任務(等待定時器到時執行) 執行宏任務1 // 1 // 5 // 3 // 10 // 4 // 7 // 8 // 9 // 2
總結:promise