非同步程式設計
Dart 庫中充滿了返回 Future 或 Stream 物件的函式。這些函式是非同步的:它們在設定一個可能耗時的操作(例如 I/O)後立即返回,而無需等待該操作完成。
async 和 await 關鍵字支援非同步程式設計,讓您能夠編寫看起來與同步程式碼相似的非同步程式碼。
處理 Future
#當您需要已完成 Future 的結果時,您有兩種選擇
- 使用
async和await,如本文和非同步程式設計教程中所述。 - 使用 Future API,如
dart:async文件中所述。
使用 async 和 await 的程式碼是非同步的,但它看起來很像同步程式碼。例如,以下程式碼使用 await 等待非同步函式的結果
await lookUpVersion();要使用 await,程式碼必須在 async 函式中——即標記為 async 的函式
Future<void> checkVersion() async {
var version = await lookUpVersion();
// Do something with version
}在使用 await 的程式碼中,使用 try、catch 和 finally 來處理錯誤和清理
try {
version = await lookUpVersion();
} catch (e) {
// React to inability to look up the version
}您可以在 async 函式中多次使用 await。例如,以下程式碼三次等待函式的結果
var entrypoint = await findEntryPoint();
var exitCode = await runExecutable(entrypoint, args);
await flushThenExit(exitCode);在 await expression 中,expression 的值通常是 Future;如果不是,則該值會自動包裝在 Future 中。此 Future 物件表示返回物件的承諾。await expression 的值是該返回的物件。await 表示式會使執行暫停,直到該物件可用。
如果在 await 時遇到編譯時錯誤,請確保 await 位於 async 函式中。例如,要在應用的 main() 函式中使用 await,main() 的函式體必須標記為 async
void main() async {
checkVersion();
print('In main: version is ${await lookUpVersion()}');
}有關使用 Future、async 和 await 的互動式介紹,請參閱非同步程式設計教程。
宣告非同步函式
#async 函式是其函式體用 async 修飾符標記的函式。
將 async 關鍵字新增到函式會使其返回一個 Future。例如,考慮這個返回 String 的同步函式
String lookUpVersion() => '1.0.0';如果您將其更改為 async 函式——例如,因為未來的實現將是耗時的——那麼返回的值將是一個 Future
Future<String> lookUpVersion() async => '1.0.0';請注意,函式的函式體不需要使用 Future API。如有必要,Dart 會建立 Future 物件。如果您的函式不返回有用的值,請將其返回型別設定為 Future<void>。
有關使用 Future、async 和 await 的互動式介紹,請參閱非同步程式設計教程。
處理 Stream
#當您需要從 Stream 獲取值時,您有兩種選擇
- 使用
async和非同步 for 迴圈 (await for)。 - 使用 Stream API,如
dart:async文件中所述。
非同步 for 迴圈具有以下形式
await for (varOrType identifier in expression) {
// Executes each time the stream emits a value.
}表示式 的值必須是 Stream 型別。執行過程如下
- 等待直到 Stream 發出一個值。
- 執行 for 迴圈體,並將變數設定為該發出的值。
- 重複 1 和 2,直到 Stream 關閉。
要停止監聽 Stream,您可以使用 break 或 return 語句,它們會跳出 for 迴圈並取消訂閱 Stream。
如果在實現非同步 for 迴圈時遇到編譯時錯誤,請確保 await for 位於 async 函式中。例如,要在應用的 main() 函式中使用非同步 for 迴圈,main() 的函式體必須標記為 async
void main() async {
// ...
await for (final request in requestServer) {
handleRequest(request);
}
// ...
}有關 Dart 非同步程式設計支援的更多資訊,請查閱 dart:async 庫文件。