
Dart庫充滿了返回Future或Stream對象的函數(shù)。這些函數(shù)是異步的:它們在設置一個可能耗時的操作(如I / O )后返回,而無需等待該操作完成。
async和await關鍵字支持異步編程,允許你編寫看起來類似于同步代碼的異步代碼。
處理Futures
當你需要一個完整Futures的結果時,你有兩個選擇:
- 使用
async和await - 使用Futures的API
使用async和await的代碼是異步的,但是看起來很像同步代碼。例如,以下代碼使用await來等待異步函數(shù)的結果:
await lookUpVersion();
使用await,代碼必須是在一個*異步函數(shù)(async function)里-標記為async的異步函數(shù):
Future checkVersion() async {
var version = await lookUpVersion();
// 用version變量做點什么
}
注意:雖然異步函數(shù)可能會執(zhí)行耗時的操作,但它不會等待這些操作。相反,異步函數(shù)只在遇到它的第一個
await表達式之前執(zhí)行。然后,它返回一個Future的對象,只有在await表達式完成后,才恢復執(zhí)行。
使用try,catch和finally,最后在使用await的代碼去處理錯誤和清理后續(xù)邏輯
try {
version = await lookUpVersion();
} catch (e) {
// 無法查找到version做出反應
}
你可以在異步函數(shù)中多次使用await。例如,下面的代碼等待函數(shù)結果三次:
var entrypoint = await findEntrypoint();
var exitCode = await runExecutable(entrypoint, args);
await flushThenExit(exitCode);
在await 表達式中,表達式的值通常是一個Future;如果不是,則該值將在Future中自動包裝。這個Future的對象表示承諾返回一個對象。await expression的值就是那返回的對象。await表達式使程序運行停止,直到對象可用!
如果當你使用await的時候,遇到到一個編譯時錯誤。此時請確保await是否處于異步函數(shù)中。例如,在app的main()函數(shù)中使用await,則main()主主體必須標志為async即異步
Future main() async {
checkVersion();
print('In main: version is ${await lookUpVersion()}');
}
聲明異步函數(shù)
當一個函數(shù)主體被async修飾符標志,那么這個函數(shù)就是一個異步函數(shù)
將async關鍵字添加到函數(shù)中會使它返回Future。例如,看下這個同步函數(shù),它返回一個字符串:
String lookUpVersion() => '1.0.0';
請注意,函數(shù)的主體不需要使用Future的API。如果需要,dart會創(chuàng)建Future的對象。
如果你的函數(shù)沒有任何有用的值,請將其返回類型設為Future<void> 。
處理流
當你需要從流中獲取值時,有兩個選項:
- 使用
async和異步循環(huán)(await for) - 使用流API
注意:在使用
await for之前,請確保它能使代碼更加清晰,并且你確實希望等待流的所有結果。例如,你通常不應該為UI事件偵聽器使用await for,因為UI框架發(fā)送無盡的事件流。
異步for循環(huán)具有以下形式:
await for (varOrType identifier in expression) {
//每次流發(fā)出值時執(zhí)行
}
表達式的值必須具有類型流。執(zhí)行過程如下:
- 等到流發(fā)出一個值。
- 執(zhí)行for循環(huán)的主體,將變量設置為該發(fā)出的值。
- 重復第1步和第2步,直至流關閉。
若要停止偵聽流,可以使用break或return語句,該語句脫離for循環(huán)并取消訂閱流。
如果在實現(xiàn)異步for循環(huán)時遇到編譯時錯誤,請確保await for在異步函數(shù)中。例如,要在應用程序的main()函數(shù)中使用異步for循環(huán),main()的主體必須標記為async(異步):
Future main() async {
// ...
await for (var request in requestServer) {
handleRequest(request);
}
// ...
}
有關異步編程的更多信息,一般來說,請參見庫教程的dart:async
。另請參見文章Dart Language Asynchrony Support: Phase 1和 Dart Language Asynchrony Support: Phase 2,以及 Dart language specification
。
PS:本文
整理自官方文檔,若有發(fā)現(xiàn)問題請致郵 caoyanglee92@gmail.com