Stream Controller
CoddyのDartジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 78/110。
async* ジェネレータは、事前に定義されたデータを使用してストリームを作成するのに適していますが、コードのさまざまな部分からストリームにデータを追加するなど、より詳細な制御が必要な場合があります。そこで StreamController の出番です。
StreamController はストリームのマネージャーとして機能します。これは、データを追加するための「sink」と、リスナーが購読できる「stream」を提供します:
import 'dart:async';
void main() {
var controller = StreamController<String>();
// ストリームをリッスンします
controller.stream.listen((data) {
print('Received: $data');
});
// シンク経由でデータを追加します
controller.add('Hello');
controller.add('World');
controller.close(); // 完了したら必ずクローズしてください
}add() メソッドは新しい値をストリームにプッシュし、リスナーはそれらを即座に受け取ります。リソースを解放するために、終了したときには常に close() を呼び出す必要があります。
デフォルトでは、ストリームは1つのリスナーしか持つことができません。複数のリスナーが必要な場合は、ブロードキャストコントローラを使用します:
import 'dart:async';
void main() {
var controller = StreamController<int>.broadcast();
controller.stream.listen((n) => print('Listener 1: $n'));
controller.stream.listen((n) => print('Listener 2: $n'));
controller.add(42);
controller.close();
}StreamControllersは、データの変更時にアプリの複数の部分に通知したり、ユーザーのアクションを処理したり、オブジェクト内のリアルタイム更新を管理したりするなど、イベント駆動型のクラスを構築するためにOOPにおいて不可欠です。
チャレンジ
簡単複数のサブスクライバーがリアルタイムでメッセージを受信できるメッセージハブシステムを構築しましょう!StreamController を使用してメッセージの流れを管理し、ブロードキャストストリームによって複数のリスナーが可能になる仕組みを実演します。
コードを2つのファイルに分けて構成します:
message_hub.dart: StreamController を使用してメッセージ配信を管理するMessageHubクラスを作成します。ハブは以下の機能を備えている必要があります:- 複数のリスナーが購読できるように、内部でブロードキャスト
StreamController<String>を使用する - リスナーが購読するためのストリームを返す
messagesというゲッターを提供する - ストリームにメッセージを追加する
broadcast(String message)メソッドを持つ - コントローラーを閉じる
shutdown()メソッドを持つ
- 複数のリスナーが購読できるように、内部でブロードキャスト
main.dart: メッセージハブをインポートし、同じストリームをリッスンする複数のサブスクライバーを設定するシナリオを作成します:MessageHubインスタンスを作成するSubscriber A: [message]という形式でメッセージを出力する1つ目のリスナーを追加するSubscriber B: [message]という形式でメッセージを出力する2つ目のリスナーを追加する- 3つのメッセージ
Hello everyone、Welcome to the hub、Goodbyeをブロードキャストする - ハブをシャットダウンする
StreamController にアクセスするために、メッセージハブファイルで dart:async をインポートすることを忘れないでください。両方のサブスクライバーがブロードキャストされたすべてのメッセージを受信することに注目してください。これがブロードキャストストリームの強力な点です!
期待される出力:
Subscriber A: Hello everyone
Subscriber B: Hello everyone
Subscriber A: Welcome to the hub
Subscriber B: Welcome to the hub
Subscriber A: Goodbye
Subscriber B: Goodbyeチートシート
StreamControllerはストリームを管理し、つ、どのようにデータが追加されるかを制御します。データを追加するための「sink」と、リスナーが購読できる「stream」を提供します。
基本的な使い方:
import 'dart:async';
var controller = StreamController<String>();
// Listen to the stream
controller.stream.listen((data) {
print('Received: $data');
});
// Add data through the sink
controller.add('Hello');
controller.add('World');
controller.close(); // Always close when done
add()メソッドは、新しい値をストリームにプッシュします。リスナーはそれらを即座に受け取ります。リソースを解放するために、終了時には必ずclose()を呼び出してください。
デフォルトでは、ストリームは1つのリスナーしか持つことができません。複数のリスナーが必要な場合は、ブロードキャストコントローラーを使用します:
var controller = StreamController<int>.broadcast();
controller.stream.listen((n) => print('Listener 1: $n'));
controller.stream.listen((n) => print('Listener 2: $n'));
controller.add(42);
controller.close();
StreamControllerは、イベント駆動型のクラスの構築、データ変更時のアプリの複数箇所への通知、ユーザーアクションの処理、またはリアルタイム更新の管理に不可欠です。
自分で試してみよう
import 'message_hub.dart';
void main() {
// TODO: MessageHub インスタンスを作成する
// TODO: 「Subscriber A: [message]」と出力する最初のリスナーを追加する
// TODO: 「Subscriber B: [message]」と出力する2番目のリスナーを追加する
// TODO: 3つのメッセージをブロードキャストする:
// - "Hello everyone"
// - "Welcome to the hub"
// - "Goodbye"
// TODO: ハブをシャットダウンする
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
4Null Safety
Null Safety 入門Nullable と Non-Nullable? 演算子と ! 演算子late キーワードと Null SafetyNull-Aware 演算子クラスにおける Null Safetyまとめ:ユーザープロフィールシステム10コレクションとジェネリクス
List, Set, Map の概要型安全なコレクションジェネリッククラスジェネリックメソッドジェネリクスの制約Iterable と Iteratorまとめ:ジェネリックなストレージ12非同期 OOP
Future と async/awaitStream の基礎Stream Controller非同期コンストラクタクラスメソッドにおける非同期処理まとめ - Data Fetcher