async await函式的執行順序的理解

2021-09-01 05:35:14 字數 3615 閱讀 7196

最近遇到乙個關於async函式使用的bug,因**涉及太多業務,所以模擬了**, 如下:

let testarr =[1

,2,3

]let flag =

false

const

func

=(res)

=>})

}testarr.

foreach

(async

(item)

=>)}

)console.

log(

'flag'

, flag)

當時寫**的人的目的很簡單,就是要讓非同步函式變成同步來執行,按如下輸出:

res 1

true

res 2

true

res 3

true

flag true

但實際輸出的是:

flag false

res 1

true

res 2

true

res 3

true

當時我也覺得奇怪的,為什麼await沒有生效?真的沒有生效?

於是我在await 後面加了乙個console.log(『inside』, flag), **如下

let testarr =[1

,2,3

]let flag =

false

const

func

=(res)

=>})

}testarr.

map(

async

(item)

=>

) console.

log(

'inside'

, flag)})

console.

log(

'flag'

, flag)

輸出如下

flag false

res 1

true

res 2

true

res 3

true

inside true

inside true

inside true

也就是說,其實在函式裡面await是生效了?那為是什麼外面就沒有生效?

很多人以為await會一直等待之後的表示式執行完之後才會繼續執行後面的**,實際上await是乙個讓出執行緒的標誌

await後面的函式會先執行一遍,然後就會跳出整個async函式來執行後面js棧的**。

等本輪事件迴圈執行完了之後又會跳回到async函式中等待await後面表示式的返回值。

如果返回值為非promise,則繼續執行async函式後面的**,

否則將返回的promise,放入promise佇列(promise的job queue), 然後等待promise任務佇列執行完之後,再執行await後面的**

所以,如果要讓flag變成true,需要再用乙個async函式,修改的**如下:

let testarr =[1

,2,3

]let flag =

false

const

func

=(res)

=>})

}async

function

container()

) console.

log(

'inside'

, flag)})

console.

log(

'flag'

, flag)

}container

()

輸出:

res 1

true

res 2

true

res 3

true

flag true

inside true

inside true

inside true

從其他博主看到這樣一段**,我覺得非常經典:

function

testsometing()

async

function

testasync()

async

function

test()

test()

;var promise =

newpromise

((resolve)

=>);

//關鍵點2

promise.

then

((val)

=> console.

log(val));

console.

log(

"test end..."

)

輸出:

test start...

執行testsometing

promise start.

.test end...

testsometing

執行testasync

promise //第七位

hello async

testsometing hello async

調整了一下**順序

function

testsometing()

async

function

testasync()

async

function

test()

test()

;var promise =

newpromise

((resolve)

=>);

//關鍵點2

promise.

then

((val)

=> console.

log(val));

console.

log(

"test end..."

)

輸出:

test start...

執行testasync

promise start.

.test end...

promise //第五位

hello async

執行testsometing

testsometing

testsometing hello async

區別主要是』promise』的出現的位置,所以:

如果返回值為非promise,則繼續執行async函式後面的**,哪怕外面已經有任務佇列在排隊

否則將返回的promise,放入promise佇列(promise的job queue), 然後等待promise任務佇列執行完之後,再執行await後面的**

async await執行順序面試題

async function async1 async function async2 console.log script start settimeout function 0 async1 new promise function resolve then function console.l...

vue 鉤子函式 使用async await

示例 vue async created 100 5的輸出順序也不是在1後面 console.log 5 async mounted 100 6的輸出順序也不是在2後面 console.log 6 通過設定created和mounted中定時時間不同,檢視控制台輸出順序。完全亂套!只能保證最先輸出3...

async await使用的要點

async await的使用 1 如果乙個方法標註了async,則其返回值只能是 void,task,task三者之一 2 如果非同步方法中沒有await,那麼這個方法將會以同步方式執行 3 單個async方法中可以擁有多個await 4 當遇到await表示式時,呼叫執行緒將會掛起,知道await...