之前翻看別的大佬的博客看到了關於setTimeout,promise還有async執行順序的文章。觀看了幾篇之后還是沒有怎么看懂,於是自己開始分析代碼,並整理了此文章,我相信通過此文章朋友們能對異步同步還有,setTimeout,Promise,async這些內容了然於胸,接下來讓我們走入正題:
這是別的大佬博客里面的代碼:
async function async1() { console.log('async1 start') await async2() console.log('async1 end') } async function async2() { console.log('async2') } console.log('script start') setTimeout(() => { console.log('setTimeout') },0) async1() new Promise((resolve) => { console.log('promise1') resolve() }).then(() => { console.log('promise2') }) console.log('script end')
執行結果(不同瀏覽器執行結果可能不同,筆者用的谷歌):
PS:下面的關鍵點筆者都用加粗給朋友們圈起來了哦,請仔細觀看
筆者這時候開啟了雙屏模式,看它的這個代碼的執行結果去猜它的規律,然后再看MDN文檔,結果就一目了然了。
我們現在一起來分析代碼:
這只是定義了倆個異步函數(),並沒有調用,所以暫時不用管。
這是同步的內容,所以會直接執行
1.輸出 script start
setTimeout是一個計時器,異步的,所以被扔到了任務隊列里面,暫時不去管,我們只需要記住異步隊列里面有他就可以。
調用了async1函數,會走入到這個函數里,我們先再看一下這個函數:
PS:注意點:
當調用async函數的時候會返回一個Promise對象。Promise對象是立即執行的,后面會詳細介紹。
這時候會
2.輸出async1 start,
而后到了await async2()
這里需要注意一下,在async里遇到await它會使async函數暫停執行,執行完async里的await內容后將后續的內容扔入到瀏覽器的任務隊列里面去。
所以這里輸出了async1 start后又
3.輸出了async2
async2執行完畢之后又走回到調用了async1的位置。將async1沒有執行的部分扔到了任務隊列里面去。(現在任務隊列里面有一個setTimeout和一個async1的后續內容)
接下來又走到了Promise:
Promise是立即執行的,所以它會立即
4.輸出promise1。
而后是執行了resolve。執行成功,執行成功的話會走入promise的.then方法里,可是它是異步的回調函數,所以會被丟入到任務隊列里。(現在任務隊列里面有一個setTimeout和一個async1的后續內容在加上promise的.then內容)
最后走到了:
因為它是同步的,所以會直接執行。
5.輸出:script end
前五個我們都分析完畢了,接下來到關鍵點了:
現在異步隊列中有三個任務分別是:
setTimeout
async1的后續內容
promise的.then內容
這三個內容setTimeout會在最后執行,就好比css權重的優先級,大家固定記住就可以,setTimeout的優先級沒有async和promise級別高(其實async和promise是一樣的,因為調用async方法時就是返回一個promise對象)
而后async和promise的.then就看誰先進入到的任務隊列里面,任務隊列里面有先進先出的概念。所以結果很明顯了,它們三個的輸出順序是:
6.輸出:async1 end
7.輸出:promise2
8.輸出:setTimeout
在給朋友們隨便寫一個代碼,大家一起猜一下執行結果會是什么:
setTimeout(() => { console.log('setTimeout') }, 0) console.log('t1') fetch('http://dict.qq.com') .then(function(response) { return response.json(); }) .then(function(myJson) { console.log('myJson'); }) .catch(function(err) { console.log(err) }) console.log('fetch zhi hou') async function async1() { console.log('async1 start') await async2() console.log('async1 end') } async1() console.log('t2') new Promise((resolve) => { console.log('promise') resolve() }).then(() => { console.log('promise.then') }) console.log('t3') async function async2() { console.log('async2') } console.log('t4')
執行結果:
最后依次執行fetch的 .then / .catch