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')
這道面試題主要的考點是宏任務和微任務,所以我們需要先了解宏任務和微任務。
宏任務
宏任務指執行棧中待執行的任務,計時器,事件回調,http回調
都是宏任務。
微任務
微任務指執行棧清空後立即執行的任務(VIP通道,貴族就是不一樣~
),Promise 和 MutationObserver
都是微任務。
我們來分析下題目,首先從上至下依次執行
async function async1 () {
console.log('async1 start');
await async2();
console.log('async1 end')
}
async function async2 () {
console.log('async2')
}
函數創建未執行,所以不輸出;
console.log('script start');
此處第一次輸出script start
;
setTimeout(function () {
console.log('setTimeout')
}, 0);
定時器,將任務放在宏任務中;
async1();
執行async1
函數,此處輸出async1 start
,在async1
函數中調用async2
函數;此處輸出async2
後在微隊列等待執行棧完成任務後執行。
new Promise(function (resolve) {
console.log('promise1');
resolve()
}).then(function () {
console.log('promise2')
});
依次往下執行new Promise()
輸出promise1
完成後,Promise.then
推送至微隊列排隊;
console.log('script end')
依次往下同步執行輸出script end
,此時執行棧清空,開始執行微隊列輸出async1 end
和promise2
;微隊列執行完成後執行宏隊列,輸出setTimeout
。
總結
- 先執行同步和立即執行任務,比如說
console.log()、new Promise()
- 再依次執行微任務,比如說
thenable
函數和catchable
函數 - 當微任務執行完成後開始執行宏任務,比如說
定時器、事件回調
等