假設我有兩個異步函式:
async f(): Promise<void> {
flag = true;
await computation();
}
async g(): Promise<void> {
doPreparation(); // synchronous
f();
}
據我了解,如果我在f()呼叫前加上await,那么此時運行時可以自由安排f稍后執行,并且可以選擇同時運行其他一些代碼。
我想要的是使g傳遞執行f同步,即flag = true應該嚴格在doPreparation()沒有收益的情況下運行(我也不希望computation()同步運行)。這似乎是一個公平的要求,因為這f是g.
是否有保證以f這種方式運行異步?
uj5u.com熱心網友回復:
無論哪種方式, withawait f()或 just f(),f()當解釋器遇到該行代碼時都會立即呼叫。
不同await之處在于執行 NEXT 行代碼的時間。
對于async函式中的最后一行代碼,您可以這樣做:
return f();
沒有必要await在函式的最后一行使用,async除非你也把它用 a 包圍try/catch并且試圖在函式中本地捕獲拒絕。
所以,這兩個是相同的:
async g(): Promise<void> {
doPreparation(); // synchronous
return f(); // asynchronous, f() returns a promise
}
和
async g(): Promise<void> {
doPreparation(); // synchronous
let x = await f(); // asynchronous, f() returns a promise
return x;
}
或者,如果f()回傳的 promise 有一個未定義的決議值,那么這也是一樣的:
async g(): Promise<void> {
doPreparation(); // synchronous
await f(); // asynchronous, f() returns a promise
}
這不一樣:
async g(): Promise<void> {
doPreparation(); // synchronous
f(); // asynchronous, f() returns a promise
}
因為在這種情況下,回傳的承諾g()將在回傳的承諾被解決之前f()解決。實際上,g()回傳的承諾將與承諾完全脫節f()。在這種情況下,f()就是一勞永逸,任何人都無法知道它何時完成,或者任何人都無法捕捉/處理其錯誤。如果f()在最后一種情況下被拒絕,那么您的應用將收到未處理的拒絕,這絕不是一件好事。
uj5u.com熱心網友回復:
可以使用這樣的代碼,但它有缺點:
如果
f拒絕,它就不可能被g. 回傳 Promise 通常更有意義,以便呼叫者可以根據需要對其進行處理。如果您不想退回它,那么為了避免未處理的拒絕,.catch請在f. 因為你沒有awaiting 或returning 任何東西,g也可能是一個普通的函式/方法。g() { doPreparation(); f() .catch(handleErrors); }f仍將立即運行。就像 Promise 建構式一樣,在呼叫函式和函式運行之間不會有任何延遲——至少直到await遇到 an 為止。g只有在computation完成計算后,問題中的代碼才會將控制權交還給呼叫者;如果computation價格昂貴,那可能是個問題。最好使用 web worker 將任務放在單獨的執行緒上,或者至少使用setTimeout(computation)加上所需的錯誤處理。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/517349.html
標籤:打字稿异步等待承诺
