考慮以下代碼:
示例 A:
Future<void> fakeCall() async {
await Future.delayed(const Duration(milliseconds: 300), () {
throw MyError('myException');
});
}
Future<void> fetch() async {
Future<void> testFuture = fakeCall();
testFuture.whenComplete(() {
print('when completed');
});
testFuture.catchError((e) {
print('on error');
});
return testFuture;
}
void main() async {
try{
await fetch();
}on MyError catch(e){
//getting here but one still leaks!!
}
}
打電話時,await fetch()我希望只catchError被打電話。但是錯誤以某種方式泄漏,所以基本上有兩個被拋出......一個被捕獲catchError,一個被作為未處理的錯誤泄漏到外面。
但是當使用它時建議的方式(一個接一個地鏈接):
示例B:
Future<void> fakeCall() async {
await Future.delayed(const Duration(milliseconds: 300), () {
throw MyError('myException');
});
}
Future<void> fetch() async {
Future<void> testFuture = fakeCall().whenComplete(() {
print('when completed');
}).catchError((e) {
print('on error');
});
return testFuture;
}
void main() async {
try{
await fetch();
}on MyError catch(e){
//getting here and nothing leaks!!
}
}
不會發生錯誤泄漏。它只是讓我很好奇, 有人可以解釋為什么以第一種方式撰寫它會導致錯誤泄漏嗎?
更新
最初我忘記在 fetch 函式周圍添加 try/catch,所以您可能會認為錯誤因此泄漏。但請注意,當未正確鏈接 one rror 時,錯誤仍然會泄漏(第一個示例)
uj5u.com熱心網友回復:
錯誤被泄露是因為您正在等待結果Future,最終完成時出現以下錯誤:
await fetch();
重要的是要理解一個Future物件只是一個值,它有時會在將來獲得一個值,這個值可以是一個值,也可以是一個錯誤。
如果作為錯誤完成,這catchError()是一種訂閱要執行的代碼的方法。Future該方法回傳一個新的未來,其邏輯是在原始未來完成且沒有任何錯誤的情況下獲取原始值。但是,如果源因錯誤而完成,則catchError()運行指定的方法并在執行后回傳值。
catchError()不會改變關于來源的任何內容,因此Future您可以catchError()根據需要多次呼叫。
我應該補充一點,我認為在帶有await異步標記的函式中使用傳統的 try...catch (與 結合)而不是使用 with更好,catchError()因為它使代碼更具可讀性和更少的混亂:
Future<void> fetch() async {
try {
await fakeCall();
} catch (e) {
print('on error');
} finally {
print('when completed');
}
}
void main() async {
await fetch();
}
輸出:
on error
when completed
問題更改后更新
“示例 B”的問題在于您假設它whenComplete()確實處理了任何錯誤。但是,如果您閱讀檔案:
此呼叫回傳的future
f將與此future 以相同的方式完成,除非呼叫中發生錯誤action,或者呼叫回傳的Future 中發生錯誤action。如果呼叫action不回傳未來,則忽略其回傳值。
https://api.dart.dev/stable/2.15.1/dart-async/Future/whenComplete.html
所以回傳的Future并沒有改變它的行為,所以如果源Future以錯誤完成,那么Future創建的 from也會發生同樣的情況whenComplete()。而且由于您沒有對此附加任何錯誤處理,因此Future您的程式將失敗。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/414261.html
標籤:
上一篇:函式內部的函式與主體一起運行
