iT邦幫忙

2022 iThome 鐵人賽

DAY 24
0
自我挑戰組

30天學習flutter系列 第 24

24.關於flutter的非同步處理(二)

  • 分享至 

  • xImage
  •  

Stream使用

Stream是一系列非同步事件的sequence,當你向他請求數據時,Stream不會立刻返回給你,而是在當完成時,再通知你

接收Stream事件

透過非同步的for循環(await for)來迭帶Strean中的事件,當循環結束時,函數會暫停直到下一個事件到達或Stream完成

Stream的類型

Single-Subscription(訂閱)

一個Stream只包含了某個眾多事件序列的一個。而這些事件需要按順序提供並且不能丟失。(ex.當讀取一個文件或接收一個網頁請求時)

Single-Subscription類型只能設置單次監聽,重複設置會使原來事件遺失,導致監聽到剩下其他事件毫無意義

Broadcast(廣播)

這類類型是針對單個消息,並且可以一次處理一個消息。(ex.可以將其用於瀏覽器的鼠標事件)

可以在任何時候監聽這種Stream,並且在此之後你可以獲取到任何觸發的事件。

並且可以在同一時間設置多個不同的監聽器同時監聽,同時你也可以在取消上一個訂閱後再次對其發起監聽

Stream

  • StreamController:

帶有控制流方法的Stream。可以向它的Stream發送數據、錯誤和完成事件,也可以檢查數據流是否已暫停,是否有監聽器

  • StreamSink:

Stream事件的入口。提供addaddErroraddStream方法向Stream發送事件

  • StreamSubscription

Stream的監聽器。提供cacenlpauseresume等方法來進行管理

  • StreamBuilder

使用Stream裡的數據來渲染UI裡的Widget

Stream的創建

  1. 從現有的Stream透過mapwheretakeWhile等方法,來生成一個新的Stream
// Stream
Stream<int> intNum = StreamController<int>().stream;

Stream<int> evenIntNum = intNum.where((int n) => n.isEven);
Stream<int> doubleIntNum = intNum.map((int n) => n * 2);
// 整數n>5的Stream
Stream<int> biggerFiveIntNum = intNum.takeWhile((int n) => n > 5);

  1. 使用async*yield或是Future生成
// By async* and yield
Stream<int> countNum(int to) async* {
  for (int i = 1; i <= to; i++) {
    yield i;
  }
}

Stream stream = countNum(10);
stream.listen(print);

// By Future
Future<int> sumNum(Stream<int> stream) async {
  var sum = 0;
  await for (final value in stream) {
    sum += value;
  }
  return sum;
}

var sum = await sumNum(stream);
print(sum); // 55
  1. 使用StreamController

StreamController 可以為你生成一個 Stream,並提供在任何時候、任何地方將事件添加到該 Stream 的方法

ex.Link

// bad
// NOTE: This implementation is FLAWED!
// It starts before it has subscribers, and it doesn't implement pause.
Stream<int> timedCounter(Duration interval, [int? maxCount]) {
  var controller = StreamController<int>();
  int counter = 0;
  void tick(Timer timer) {
    counter++;
    controller.add(counter); // Ask stream to send counter values as event.
    if (maxCount != null && counter >= maxCount) {
      timer.cancel();
      controller.close(); // Ask stream to shut down and tell listeners.
    }
  }

  Timer.periodic(interval, tick); // BAD: Starts before it has subscribers.
  return controller.stream;
}

// alternative created
var counterStream = timedCounter(const Duration(seconds: 1), 15);
counterStream.listen(print); // Print an integer every second, 15 times.

上一篇
23.關於flutter的非同步處理(一)
下一篇
25.關於flutter的優化 (一)
系列文
30天學習flutter30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言