一篇文章完全搞懂異步,同步,setTimeout,Promise,async

以前翻看別的大佬的博客看到了關於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

 

PS:下面的關鍵點筆者都用加粗給朋友們圈起來了哦,請仔細觀看

筆者這時候開啓了雙屏模式,看它的這個代碼的執行結果去猜它的規律,而後再看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

相關文章
相關標籤/搜索