Dart Streamクラス概要

Dar言語StreamクラスtoSet()メソッドDart

Dart Streamクラスの概要ついてメモ書き。公式はこちら

Streamは非同期処理を扱うクラス。dart:asyncライブラリで提供している。dart:asyncライブラリはdart:coreライブラリを通して使用できる。
非同期を扱うクラスにFutureがある。FutureとStreamの違いとして、Futureは単発イベントで使用するのに対して、Streamは連続したイベントを扱う場合に使用する。

例として、非同期ジェネレータのasync*関数でStreamを返してみる。
通常関数は1つの戻り値を返すが、ジェネレータ関数は複数の戻り値を返せる。
async*関数は”return”ではなく”yield”を使って戻り値を返す。コーディングで確認。

void main() {
  Stream<String> test() async* {
    List<String> ts = ["a", "b", "c"];
    for (var i in ts) {
      // Streamオブジェクトとしてts配列の値を返す。
      yield i;
    }
  }
  // listen()でStreamSubscriptionオブジェクトを受け取る。
  test().listen((event) {
    print(event);
  });
}

実行結果。

a
b
c

test()関数はStream<String>オブジェクトとして”a”, “b”, “c”を1文字づつ返している。受信側のlisten()にはイベントとしてStreamSubscriptionオブジェクトが引数として渡される。このオブジェクトを受け取ることでtest()関数の戻り値を使用できる。
Streamはデータを分割送信でき、かつlisten()で受け取ったデータはすぐに使用できる。動画のストリーミング再生、チャット、大容量データの分割送信等をイメージするとStreamの使用用途が理解できると思う。

話は逸れるが、以下のように別途定義したジェネレータ関数の値を戻り値を返す場合は、”yield*”を使用する。

void main() {
  Stream<int> test() async* {
    yield* testInt();
  }

  test().listen((event) {
    print(event);
  });
}

Stream<int> testInt() async* {
  for (int i = 0; i < 3; i++) {
    yield i;
  }
}

実行結果。

0
1
2

await for文を使うこともできる。この場合はyieldを使用する。

void main() {
  Stream<int> test() async* {
    await for (int i in testInt()) {
      yield i;
    }
    ;
  }

  test().listen((event) {
    print(event);
  });
}

Stream<int> testInt() async* {
  for (int i = 0; i < 3; i++) {
    yield i;
  }
}

話をStreamに戻す。
Streamは2種類ある。一つは”Single-subscription”で、もう一つは “broadcast” だ。

Single-subscriptionはリスナーと一対一の通信をする場合に使用する。リスナーが準備できていなければ送信できず、またリスナーがクローズするとそれ以上データを送信できない。Single-subscriptionはasync*関数によって生成され、関数を実行する度に新しいStreamが生成される。実行中にリスナーを新しく生成した場合は、最初に生成したリスナーはキャンセルされてしまう。ファイルI/Oの受信など、大きな連続データをストリーミングする時に使用する。
Single-subscriptionを複数のリスナーが同時に受信する場合はasBroadcastStreamを使用する。

broadcastは複数のリスナーを相手に通信ができ、リスナーがいなくてもStreamイベントを発行できる。ただし、Streamイベント発行中にリスナーが追加された場合、そのリスナーは発行中のイベントを受信できない。また、リスナーがイベントの受信をキャンセルすると、受信は即時停止する。
“done”イベントを発行すると、リスナーのサブスクリプションは解除される。

Streamは”pause”リクエストを優先する。pauseはバッファリングを伴う場合があるが、処理を一時停止できる。

broadcastかそうでないかはisBroadcastプロパティで判断する。isBroadcastがtrueの場合はbroadcastとして動作している。

コンストラクタ等の詳細については別途記載する。

コメント

タイトルとURLをコピーしました