以前翻看別的大佬的博客看到了關於setTimeout,promise還有async執行順序的文章。觀看了幾篇以後仍是沒有怎麼看懂,因而本身開始分析代碼,並整理了此文章,我相信經過此文章朋友們能對異步同步還有,setTimeout,Promise,async這些內容瞭然於胸,接下來讓咱們走入正題:
css
這是別的大佬博客裏面的代碼:json
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')
執行結果(不一樣瀏覽器執行結果可能不一樣,筆者用的谷歌):promise
筆者這時候開啓了雙屏模式,看它的這個代碼的執行結果去猜它的規律,而後再看MDN文檔,結果就一目瞭然了。
咱們如今一塊兒來分析代碼:瀏覽器
這只是定義了倆個異步函數(),並無調用,因此暫時不用管。異步
這是同步的內容,因此會直接執行async
1.輸出 script start函數
setTimeout是一個計時器,異步的,因此被扔到了任務隊列裏面,暫時不去管,咱們只須要記住異步隊列裏面有他就能夠。fetch
調用了async1函數,會走入到這個函數裏,咱們先再看一下這個函數:
PS:注意點:
當調用async函數的時候會返回一個Promise對象。Promise對象是當即執行的,後面會詳細介紹。spa
這時候會code
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