最近遇到乙個關於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是乙個讓出執行緒的標誌。所以,如果要讓flag變成true,需要再用乙個async函式,修改的**如下:await後面的函式會先執行一遍,然後就會跳出整個async函式來執行後面js棧的**。
等本輪事件迴圈執行完了之後又會跳回到async函式中等待await後面表示式的返回值。
如果返回值為非promise,則繼續執行async函式後面的**,
否則將返回的promise,放入promise佇列(promise的job queue), 然後等待promise任務佇列執行完之後,再執行await後面的**
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...