iT邦幫忙

2021 iThome 鐵人賽

DAY 10
0
Modern Web

Flutter web 的奇妙冒險系列 第 10

Day10 | Dart 非同步 - async/awiat

Async/Awiat

在Dart中我們可以使用 async 來代表這是一個非同步的function

Future<String> fetchData2() async => 'data';

這裡的重點是:

就算我沒有另外用 Future 的constructor「 只要是 async function 就是會回傳Future 」,因為執行緒會用非同步的方式處理的話那也就表示他並不會馬上被執行,也代表我在處理它時勢必要用Future 在處理。

回到昨天的問題「我該如何將Future裡的值取出來放到別的變數」

其實也很簡單就是使用 await 這個語法:

final data = await fetchData();
  print('$data');

但另外一個重點是 await 必須要在 async function 才能使用。

void main(List<String> arguments) async {
 
    final data = await fetchData();
    print('$data');

}

await 是一種讓我們在非同步裡使用同步的語法,意思是被加上await 的會用同步的方式在運行:

		print('n1');
    final data = await outputAfter3s('asyncData1');
    print('n2');
    final data2 = await outputAfter3s('asyncData2');
    print('n3');
    print('$data');
    print('$data2');

輸出會變成這樣:

n1
// 停頓3秒
n2
// 停頓3秒
n3
asyncData1
asyncData2

表示await 真的會使這個function 停頓三秒後再繼續往下執行,但這樣子是不是代表我整個程式都會因此被停住三秒?

我們另外宣告一個async function 並把這些非同步操作移出去:

void fetch() async {
  print('n1');
  final data = await outputAfter3s('asyncData1');
  print('n2');

  final data2 = await outputAfter3s('asyncData2');
  print('n3');

  print('$data');
  print('$data2');
}

void main(List<String> arguments) {
  fetch();
  print('Hello world');
}

還記得前面所說的「 只要是 async function 就是會回傳Future 」嗎,沒錯雖然對於這個function他是會被當作用同步的方式在執行,但對於其他function 這個async function還是非同步的,只有在async function 裡剩下的程式碼會被阻塞住。

n1
Hello world
// 停頓3秒
n2
// 停頓3秒
n3
asyncData1

那在async function 裡要如何做錯誤處理,其實就跟一般的錯誤處理一樣是使用 try catch 就好,也可以使用 finaly 用來當作try 裡面的code 執行完需要執行的部分。

try {
    throwError();
    final data = await fetchData();
    print('$data');
  } catch (err) {
    print(err);
  }finally {
    print('done');
  }

async/awiat 另外一個功用就是可以拿來處理 Stream

就如同我們用 for ... in 操作一個 List ,我們只要用 await for ... in 就可以拿來操作一個Stream

Future<int> getTotal(Stream<int> stream) async {
  var total = 0;
  await for (var number in stream) {
    total += number;
  }
  return total;
}

// ...

print(await getTotal(_numberStream));
// 10

至於什麼Stream 可以先想像成一群 Future ,就像 List 那樣只是我們在迭代 List 時可以馬上獲得結果,但 Stream 沒辦法。


今天的程式碼:

https://github.com/zxc469469/dart-playground/tree/Day10/async-await

本來是預計Stream 與Async/Awiat 放到同一篇,只是打算放在同一篇但剛好遇到最近工作較忙只好切成兩篇來撐一下文章數了,導致這篇看起來有點水QQ

參考資料

  1. https://dart.dev/codelabs/async-await#example-execution-within-async-functions
  2. https://www.youtube.com/watch?v=SmTCmDMi4BY&t=120s

上一篇
Day09 | Dart 非同步 - Future
下一篇
Day 11 | Dart 非同步 - Stream
系列文
Flutter web 的奇妙冒險30

尚未有邦友留言

立即登入留言