宏任務和微任務的一道經典面試題~

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 endpromise2;微隊列執行完成後執行宏隊列,輸出setTimeout

總結

  1. 先執行同步和立即執行任務,比如說console.log()、new Promise()
  2. 再依次執行微任務,比如說thenable函數和catchable函數
  3. 當微任務執行完成後開始執行宏任務,比如說定時器、事件回調
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章