如果您從非異步代碼呼叫異步函式,則 await 之后的任何內容都會相對于呼叫者異步運行:
async function asyncInner() {
console.log('before asyncInner');
await Promise.resolve()
console.log('after asyncInner');
}
console.log('start');
asyncInner()
console.log('end');
換句話說,這會列印:
start
before asyncInner
end
after asyncInner
但是如果你從另一個異步函式中呼叫這個異步函式:
async function asyncInner() {
console.log('before asyncInner');
await Promise.resolve()
console.log('after asyncInner');
}
async function asyncOuter() {
console.log('before asyncOuter');
await asyncInner();
console.log('after asyncOuter');
}
console.log('start');
asyncOuter()
console.log('end');
你得到:
start
before asyncOuter
before asyncInner
end
after asyncInner
after asyncOuter
換句話說,內部方法相對于外部方法同步完成。為什么會這樣,怎么能寫成asyncOuter在 之前完成asyncInner?
(我知道我可以setTimeout為此使用 a ,但我更愿意避免使用回呼,因為異步的好處之一就是避免回呼地獄。)
uj5u.com熱心網友回復:
換句話說,內部方法相對于外部方法同步完成。為什么會這樣,如何撰寫它以便 asyncOuter 在 asyncInner 之前完成?
它實際上不是同步的,但你是對的,它會等待內部函式完成,然后再繼續外部函式。它會等待的原因是因為您告訴它使用await關鍵字等待。如果您不想等待它,只需將其忽略即可。
async function asyncInner() {
console.log('before asyncInner');
await Promise.resolve()
console.log('after asyncInner');
}
async function asyncOuter() {
console.log('before asyncOuter');
asyncInner(); // <--------- removed the await
console.log('after asyncOuter');
}
console.log('start');
asyncOuter()
console.log('end');
uj5u.com熱心網友回復:
@Keith:我看到我將“同步”與“等待”混淆了。
即便如此,它還是有點模糊。 await在 Javascript 中確實是一些花哨的語法糖,promise.then(result => {}) 所以沒有什么可以等待的,它只是將回呼地獄轉換為看起來同步的東西,因此更容易推理。
如果我們洗掉await并按照使用thenable.
所以下面我將您的示例轉換為不使用await,并且如您所見,它給出了相同的結果,但這次我們使用的是回呼。因此,如果您了解回呼函式,那么您得到的結果就更有意義了。
function asyncInner() {
console.log('before asyncInner');
return Promise.resolve().then(r =>
console.log('after asyncInner'));
}
function asyncOuter() {
console.log('before asyncOuter');
return asyncInner().then(() =>
console.log('after asyncOuter'));
}
console.log('start');
asyncOuter()
console.log('end');
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/360667.html
標籤:javascript 异步 异步等待
