dart:async
庫中Future
類的用法介紹如下。
異步計算的結果。
asynchronous computation
在啟動時不能立即提供結果,這與同步計算不同,同步計算通過返回值或拋出來立即計算結果。異步計算可能需要等待程序外部的某些事情(讀取文件、查詢數據庫、獲取網頁),這需要時間。在結果可用之前,異步計算不會阻塞所有計算,而是立即返回一個Future
,它將與結果一起eventually
"complete"。
異步編程
要執行異步計算,請使用 async
函數,該函數始終會產生未來。在這樣的異步函數中,您可以使用await
操作來延遲執行,直到另一個異步計算有結果。在等待函數的執行被延遲的同時,程序並沒有被阻塞,可以繼續做其他事情。
例子:
import "dart:io";
Future<bool> fileContains(String path, String needle) async {
var haystack = await File(path).readAsString();
return haystack.contains(needle);
}
這裏來自 dart:io
的 File.readAsString
方法是一個返回 Future<String>
的異步函數。 fileContains
函數在其主體之前標有async
,這意味著您可以在其中使用await
,並且它必須返回一個未來。對File(path).readAsString()
的調用啟動將文件讀入字符串並生成最終包含結果的Future<String>
。然後 await
等待該未來以字符串完成(或錯誤,如果讀取文件失敗)。在等待期間,程序可以做其他事情。當 future 以字符串結束時,fileContains
函數計算一個布爾值並返回它,然後完成它在第一次調用時返回的原始未來。
如果未來以 error
完成,則等待該未來將(重新)拋出該錯誤。在這裏的示例中,我們可以添加錯誤檢查:
import "dart:io";
Future<bool> fileContains(String path, String needle) async {
try {
var haystack = await File(path).readAsString();
return haystack.contains(needle);
} on FileSystemException catch (exception, stack) {
_myLog.logError(exception, stack);
return false;
}
}
您使用普通的 try
/catch
來捕獲等待的異步計算的失敗。
一般來說,在編寫異步代碼時,你應該總是等待一個未來的產生,而不是等到另一個異步延遲之後。這可確保您準備好接收未來可能產生的任何錯誤,這一點很重要,因為 no-one 正在等待的異步錯誤是 uncaught
錯誤,並且可能會終止正在運行的程序。
使用Future
API 進行編程。
Future
類還提供了更直接的低級函數來訪問它完成的結果。 async
和await
語言特性建立在此函數之上,有時直接使用它是有意義的。有些事情你不能通過一次await
ing 一個未來來完成。
使用 Future ,您可以手動注冊處理值或錯誤的回調(一旦可用)。例如:
Future<int> future = getFuture();
future.then((value) => handleValue(value))
.catchError((error) => handleError(error));
由於 Future 可以通過兩種方式完成,使用值(如果異步計算成功)或錯誤(如果計算失敗),您可以為其中一種或兩種情況安裝回調。
在某些情況下,我們說未來已完成 with another future
。這是一種簡短的方式來說明未來以相同的方式完成,具有相同的值或錯誤,一旦另一個未來本身完成,另一個未來。完成未來的平台庫中的大多數函數(例如 Completer.complete 或 Future.value )也接受另一個未來,並自動處理將結果轉發到正在完成的未來。
注冊回調的結果本身就是一個 Future
,它反過來通過使用原始未來結果調用相應回調的結果來完成。如果調用的回調拋出,則新的未來完成並出現錯誤。例如:
Future<int> successor = future.then((int value) {
// Invoked when the future is completed with a value.
return 42; // The successor is completed with the value 42.
},
onError: (e) {
// Invoked when the future is completed with an error.
if (canHandle(e)) {
return 499; // The successor is completed with the value 499.
} else {
throw e; // The successor is completed with the error e.
}
});
如果未來在完成錯誤時沒有任何注冊的處理程序,它會將錯誤轉發到“uncaught-error 處理程序”。此行為可確保不會以靜默方式丟棄任何錯誤。但是,這也意味著應該盡早安裝錯誤處理程序,以便它們在未來完成時出現錯誤。以下示例演示了這個潛在的錯誤:
var future = getFuture();
Timer(const Duration(milliseconds: 5), () {
// The error-handler is not attached until 5 ms after the future has
// been received. If the future fails before that, the error is
// forwarded to the global error-handler, even though there is code
// (just below) to eventually handle the error.
future.then((value) { useValue(value); },
onError: (e) { handleError(e); });
});
注冊回調時,分別注冊兩個回調通常更具可讀性,首先使用帶有一個參數(值處理程序)的then,然後使用第二個catchError 來處理錯誤。它們中的每一個都會將它們不處理的結果轉發給它們的後繼者,它們一起處理值和錯誤結果。它還具有 catchError 處理 then 值回調中的錯誤的額外好處。使用順序處理程序而不是並行處理程序通常會導致代碼更容易推理。它還使異步代碼與同步代碼非常相似:
// Synchronous code.
try {
int value = foo();
return bar(value);
} catch (e) {
return 499;
}
基於期貨的等效異步代碼:
Future<int> asyncValue = Future(foo); // Result of foo() as a future.
asyncValue.then((int value) {
return bar(value);
}).catchError((e) {
return 499;
});
與同步代碼類似,錯誤處理程序(使用 catchError 注冊)正在處理由 foo
或 bar
引發的任何錯誤。如果 error-handler 已注冊為 then
調用的 onError
參數,則它不會捕獲來自 bar
調用的錯誤。
期貨可以注冊多個callback-pair。每個後繼者都被獨立對待,並被視為唯一的後繼者。
未來也可能永遠無法完成。在這種情況下,不會調用回調。如果可能的話,通常應該避免這種情況,除非它有非常清楚的記錄。
- 可用的擴展
相關用法
- Dart Future.doWhile用法及代碼示例
- Dart Future.any用法及代碼示例
- Dart Future.value用法及代碼示例
- Dart Future.wait用法及代碼示例
- Dart Future.whenComplete用法及代碼示例
- Dart Future.catchError用法及代碼示例
- Dart Future.error用法及代碼示例
- Dart Future.timeout用法及代碼示例
- Dart Future.sync用法及代碼示例
- Dart Future.delayed用法及代碼示例
- Dart FutureExtensions.onError用法及代碼示例
- Dart Function.apply用法及代碼示例
- Dart FileList.first用法及代碼示例
- Dart FileList.length用法及代碼示例
- Dart File用法及代碼示例
- Dart Finalizer.attach用法及代碼示例
- Dart Float32List.view用法及代碼示例
- Dart FileSystemEntity用法及代碼示例
- Dart FileSystemEntity.resolveSymbolicLinks用法及代碼示例
- Dart Finalizable用法及代碼示例
- Dart File.renameSync用法及代碼示例
- Dart Float32x4List.sublist用法及代碼示例
- Dart Finalizer用法及代碼示例
- Dart FileSystemEntity.resolveSymbolicLinksSync用法及代碼示例
- Dart FileList.elementAt用法及代碼示例
注:本文由純淨天空篩選整理自dart.dev大神的英文原創作品 Future<T> class。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。