【Flutter 1-13】Flutter手把手教程Dart語言——非同步、Future、Stream、async、await詳解

弗拉德x0發表於2020-12-05

作者 | 弗拉德
來源 | 弗拉德(公眾號:fulade_me)

非同步

Dart 程式碼庫中有大量返回FutureStream物件的函式,這些函式都是非同步的,它們會在耗時操作執行完畢前直接返回而不會等待耗時操作執行完畢。
asyncawait關鍵字用於實現非同步程式設計,並且讓你的程式碼看起來就像是同步的一樣。

Future

可以通過下面兩種方式,獲得Future執行完成的結果:

  • 使用asyncawait
  • 使用Future API

使用asyncawait的程式碼是非同步的,但是看起來有點像同步程式碼。例如,下面的程式碼使用await等待非同步函式的執行結果。

await lookUpVersion();

必須在帶有async關鍵字的非同步函式中使用 await

Future checkVersion() async {
  var version = await lookUpVersion();
  // 使用 version 繼續處理邏輯
}

儘管非同步函式可以處理耗時操作,但是它並不會等待這些耗時操作完成,非同步函式執行時會在其遇到第一個 await表示式的時候返回一個Future物件,然後等待await表示式執行完畢後繼續執行。

使用trycatch以及finally來處理使用await導致的異常:

try {
  version = await lookUpVersion();
} catch (e) {
  // 無法找到版本時做出的反應
}

你可以在非同步函式中多次使用await關鍵字。例如,下面程式碼中等待了三次函式結果:

var entrypoint = await findEntrypoint();
var exitCode = await runExecutable(entrypoint, args);
await flushThenExit(exitCode);

await表示式的返回值通常是一個Future物件;
如果不是的話也會自動將其包裹在一個Future物件裡。Future物件代表一個"承諾",await表示式會阻塞直到需要的物件返回。

如果在使用await時導致編譯錯誤,請確保await在一個非同步函式中使用。例如,如果想在main()函式中使用await,那麼main()函式就必須使用async關鍵字標識。

Future main() async {
  checkVersion();
  print('在 Main 函式中執行:版本是 ${await lookUpVersion()}');
}

宣告非同步函式

定義非同步函式只需在普通方法上加上async關鍵字即可。
將關鍵字async新增到函式並讓其返回一個Future 物件。假設有如下返回String物件的方法:

String lookUpVersion() => '1.0.0';

將其改為非同步函式,返回值是Future

Future<String> lookUpVersion() async => '1.0.0';

注意,函式體不需要使用Future API。如有必要,Dart會建立Future物件。
如果函式沒有返回有效值,需要設定其返回型別為 Future<void>

Stream

Stream也是用於接收非同步事件資料,和Future不同的是,它可以接收多個非同步操作的結果(成功或失敗)。 也就是說,在執行非同步任務時,可以通過多次觸發成功或失敗事件來傳遞結果資料或錯誤異常。Stream常用於會多次讀取資料的非同步任務場景,如網路內容下載、檔案讀寫等。舉個例子:

Stream.fromFutures([
  // 1秒後返回結果
  Future.delayed(new Duration(seconds: 1), () {
    return "hello 1";
  }),
  // 丟擲一個異常
  Future.delayed(new Duration(seconds: 2),(){
    throw AssertionError("Error");
  }),
  // 3秒後返回結果
  Future.delayed(new Duration(seconds: 3), () {
    return "hello 3";
  })
]).listen((data){
   print(data);
}, onError: (e){
   print(e.message);
},onDone: (){

});

上面的程式碼依次會輸出:

hello 1
Error
hello 3

公眾號

相關文章