async/await和then函數的執行順序

首先說結論:

       async 用來指定方法爲異步方法(區別於同步方法),即只有async修飾的函數中才能出現await阻塞操作,遇到阻塞是先讓CPU先執行函數外的操作,之後再回函數內部執行函數內接下來的代碼。而不像同步方法那樣傻傻的等待,浪費CPU資源

       await阻塞,後面放異步任務,當其執行完畢後,阻塞該函數的執行,去執行函數外的代碼

       例如:const response= await axios.get("/all")  注意這段代碼是從右邊開始執行,當前臺發出get請求後,await使得函數進入阻塞狀態(這時候response沒有賦值,因爲被await阻塞了),執行函數外的代碼。當get請求的數據回來後,函數繼續開始執行,這時候才賦值

      前端代碼執行分成很多次時間循環:每一次時間循環的先後順序是執行宏任務,微任務,渲染UI

      執行過程中遇到SetTimeOut之類的大型宏任務,那麼就把SetTimeOut內部的回調函數推入到下一個宏任務,當本輪循環全部完成後才繼續下一輪的執行

      then函數內部是微任務,在本回合的宏任務執行完成後執行

<script>
    async function async1(){
        console.log('async1 start'+new Date().getTime())
        await async2()
        console.log('async1 end'+new Date().getTime())
    }
    async function async2(){
        console.log('async2'+new Date().getTime());      
    }
    console.log('script start'+new Date().getTime())
    setTimeout(()=>{
        console.log("settimeout"+new Date().getTime())
    },500)
    async1()
    new Promise(function(resolve){
        console.log("promise construction"+new Date().getTime())
        resolve()
    }).then(function(){
        console.log('then 1'+new Date().getTime())
    }).then(function(){
        console.log('then 2'+new Date().getTime())
    })
    console.log("script end"+new Date().getTime())
</script>

首先執行setTimeOut,把裏面的回調函數推入到下一個宏任務,之後執行async1打印 async1 start

接下里執行async2,打印async2,當該函數執行完畢後,await使得async1阻塞轉而執行函數外的代碼

接下里執行Promise構造函數,打印promise construction,接下來執行then函數,由於then函數是微任務,所以要等待當前這一輪的所有的宏任務執行完成

接下來打印script end,這時候函數外的代碼都執行完成了,返回函數內執行被阻塞後的代碼,打印async 1

本輪所有的宏任務執行完畢,開始執行微任務,也是按照先後原則執行,所以先後打印then1 ,then2

本輪所有任務完成,開始執行下一輪的宏函數,打印settimeout

 

 

所以chrome瀏覽器多次輸出先後順序是 

第一輪宏任務:

script start        async1 start        async2         promise construction       script end           async1 end

第一輪微任務:

then 1         then 2

第三輪宏任務:

settimeout

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章