一篇文章徹底搞懂異步,同步,setTimeout,Promise,async


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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM