js紅任務微任務事件輪巡的面試題


今天記錄下一個關於js宏任務、微任務、事件輪巡機制的經典面試題:

  async function async1(){
      console.log("1");
      await async2();
      // async2();
      console.log("2");
    }
    async function async2(){
      console.log("3");
    }
    console.log("4");
    setTimeout(() => {
      console.log("5");
      Promise.resolve().then(function(){
        console.log("6");
      });
    }, 0);
    setTimeout(() => {
      console.log("7");
      Promise.resolve().then(function(){
        console.log("8");
      });
    }, 0);
    async1();
    new Promise(function(resolve){
      console.log("9");
      resolve();
    }).then(function(){
      console.log("10");
    });
    console.log("11");

    //斷言輸出順序
    // 4 => 1 => 3 => 9 => 11 => 10 => 2 => 5 => 7 => 6 => 8

    //結果
    // 4 => 1 => 3 => 9 => 11 => 2 => 10 => 5 => 6 => 7 => 8

這種東西,你當時看看可能就明白了。過兩天就又忘了,所以寫兩遍看兩遍可能記得牢點,然后看代碼執行順序:

(其實只要記住,宏任務是一個一個的執行,微任務是一下子全執行,執行完一個宏任務就去清空一下微任務棧,一步一步分析就OK。但前提你得知道哪些是宏任務哪些是微任務)

第一遍下來:4 => 將兩個settimeout放入宏任務任務棧 => 1 => 3 然后將await后邊的放入微任務棧 => 9 => 將then里的放入微任務棧 => 11;

然后清空微任務棧:2 => 10;

然后執行宏任務:這時候宏任務里邊放着兩個settimeout,先執行第一個:5=>將后面緊跟着的then放入微任務棧,

然后清空微任務棧:6;

然后執行宏任務:執行另一個宏任務:輸出7 => 將then后邊的放入微任務棧中;

然后清空微任務棧:8; 

當然這個是我看完運行結果之后分析的,現在說下我出錯的兩個地方,第一個簡單就是settimeout里邊加Promise這里:大意了,執行settimeout之前微任務棧是空的,執行之后微任務棧就有東西了,自己放的。然后看第二個出錯的地方是:Promise的then和await之后的誰優先,記得在哪里看到過:說then比await優先級高,是真的嗎?

  function test2(){
    async function async1(){
      console.log("1");
      await fn();
      console.log("2");
    }
    function fn(){
      console.log("3");
    }
    async1();
    new Promise((resolve,reject)=>{
      console.log("4");
      resolve();
    }).then(_=>{
      console.log("5");
    });
  }

  // test2();

  // 斷言 13425
  // 結果13425

看來不是真的,但我真的記得遇見過呀!?

還找到了:

但是我運行下:

  function test3(){
    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')
  }

  test3();
  // 斷言 script start => async1 start => async2 => promise1 => script end => async1 end => promise2 => setTimeout
  // 運行 script start => async1 start => async2 => promise1 => script end => async1 end => promise2 => setTimeout

和他說的不一樣!用node運行也是一樣!

然后一頓找:發現這個和運行環境的版本有關系,所以就不必過於深究了!WTF!

 

 

 

over!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM