promise、async和await回調隊列和事件循環 剖析

本文受https://segmentfault.com/a/1190000015057278文章啓發。

不過感覺作者寫得比較冗餘,且有些東西還是沒有講明白。於是我嘗試用更進階的代碼並配上更簡潔的註釋來講明白這些事情。

1. 事件循環

js在執行的過程中是單線程的,所以採用了事件循環機制。也就是說,從上往下執行。執行完畢 => 判斷是否微任務 => 判斷是否有宏任務

2.回調隊列

宏任務目前就簡單的理解爲setTimeout就ok了。而微任務就理解爲回調函數的回調隊列,這裏包含await promise callback。

某種意義上來說, await 是 對 promise 的封裝 , 而 promise 又是對 callback 的封裝。所以,其實是一回事兒。

即使看不懂上邊的兩點也無所謂,下面進入重點,廢話少說,直接貼代碼。

async function async1(){
    console.log('async1 start')
    console.log('async1 print',await async2())
    console.log('async1 end')
}
async function async2(){
    console.log('async2 start')
    console.log('async2 print',await async3())
    console.log('async2 end')
}
async function async3(){
    console.log('async3')
}
console.log('進程 start')
setTimeout(function(){
    console.log('setTimeout1') 
},0)  
setTimeout(function(){
    console.log('setTimeout2') 
},0)  
async1();
new Promise(function(resolve){
    console.log('promise1')
    resolve();
}).then(function(){
    console.log('promise1 resolve')
})
new Promise(function(resolve){
    console.log('promise2')
    resolve();
}).then(function(){
    console.log('promise2 resolve')
})
console.log('進程 end')

看起來其實挺繞的,如果你看了開篇那篇文章,且看不明白,那你就看我的吧。雖然更復雜,但我覺得我講得更清楚一些。


---------- 主進程開始
1. 進程start
2. 執行函數 async1, 打印 async1 start, 碰到await async2.
3. 執行函數 async2, 打印 async2 start, 碰到await async3.
4. 執行函數 async3, 打印 async3, 並返回回調隊列1,函數繼續往下執行.
5. 執行Promise , 打印promise1, 並返回回調隊列2, 函數繼續往下執行.
6. 執行Promise , 打印promise2, 並返回回調隊列3, 函數繼續往下執行。
7. 進程end
--------- 主進程結束

--- 微任務開始
---------- 回調隊列
8. 處理回調隊列1, 執行完async3, 返回給 async2, 打印 async2 print undefined, async2 end, 返回回調隊列1
9. 處理回調隊列2, 打印 promise1 resolve
10. 處理回調隊列3, 打印 promise2 resolve

---------- 第二次回調隊列
11. 處理時間隊列1, 執行完async2, 返回給 async1, 打印 async1 print undefined, async1 end, 此時回調隊列爲空

--- 微任務結束


--- 宏任務開始

---------- 執行事件循環
12. setTimeout1
13. setTimeout2

--- 宏任務結束

全部結束

也就是說最後執行的結果爲:

進程 start
async1 start
async2 start
async3
promise1
promise2
進程 end
async2 print undefined
async2 end
promise1 resolve
promise2 resolve
async1 print undefined
async1 end
setTimeout1
setTimeout2

有不明白的歡迎留言。

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