Dart 基礎之異步支持

前言

Dart庫充滿了返回FutureStream對象的函數。 這些函數都是異步的:它們在設置可能耗時的操做(例如I/O)以後返回,而無需等待該操做完成。git

asyncawait關鍵字支持異步編程,使你能夠編寫看起來相似於同步代碼的異步代碼。github

處理Futures

當你須要一個已經完成的 Future 結果,能夠有兩個方式:express

  • asyncawait
  • 用 Future API, 在庫描述中能夠找到

使用asyncawait的代碼是異步的,可是看起來很像同步代碼。 例如,下面是一些使用await等待異步函數結果的代碼:編程

await lookUpVersion();
複製代碼

要使用await代碼必須位於async函數中,該函數被標記爲async框架

Future checkVersion() async {
  var version = await lookUpVersion();
  // 用version幹些事情
}
複製代碼

注意:儘管異步功能可能會執行耗時的操做,但它不會等待這些操做。 相反,異步函數僅在遇到第一個await表達式(詳情)以前執行。 而後,它返回Future對象,僅在await表達式完成後才恢復執行。異步

使用trycatchfinally去處理錯誤,而且使用await清理代碼async

try {
  version = await lookUpVersion();
} catch (e) {
  // 應對 lookUpVersion()失敗的狀況
}
複製代碼

你能夠在async函數中屢次使用await。 例如,如下代碼等待三遍函數結果:ide

var entrypoint = await findEntrypoint();
var exitCode = await runExecutable(entrypoint, args);
await flushThenExit(exitCode);
複製代碼

await表達式中,表達式的值一般是Future; 若是不是,則該值將自動包裝在Future中。 此Future對象指示返回一個對象的承諾。 await表達式的值是返回的對象。 await表達式使執行暫停,直到該對象可用爲止。異步編程

**若是在使用await時收到編譯時錯誤,請確保awaitasync函數中。**例如,要在應用程序的main()函數中使用await,必須將main()的正文標記爲async函數

Future main() async {
  checkVersion();
  print('In main: version is ${await lookUpVersion()}');
}
複製代碼

定義異步函數

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>

有關使用futures,async和await的交互式介紹,請參見異步編程代碼實驗室

處理流

當你須要從流中獲取值,你有兩種方式:

  • async和一個異步的for循環(await for)
  • 用Stream API, 在庫描述中能夠找到

注意:在使用await以前,請確保它使代碼更清晰,而且你確確實實要等待全部流的結果。 例如,你一般不該將await用於UI事件偵聽器,由於UI框架發送無休止的事件流。

一個異步循環有如下格式:

await for (varOrType identifier in expression) {
  // 每次執行steam(流)都會發出一個值。
}
複製代碼

表達式的值必須具備Stream類型。 執行過程以下:

  1. 會等到流發出一個值爲止
  2. 執行for循環體,並將變量設置爲該發射值。
  3. 重複1和2,直到關閉流。

要中止監聽流,可使用breakreturn語句,該語句會脫離for循環並取消訂閱流。

若是在實現異步for循環時遇到編譯時錯誤,請確保await for位於async函數中。 例如,要在應用程序的main()函數中使用異步for循環,必須將main()的正文標記爲async

Future main() async {
  // ...
  await for (var request in requestServer) {
    handleRequest(request);
  }
  // ...
}
複製代碼

一般,有關異步編程的更多信息,請參見庫介紹的dart:async部分。

相關文章
相關標籤/搜索