Stream の基礎
CoddyのDartジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 77/110。
Future が単一の値を配信するのに対し、Stream は時間の経過とともに一連の値を配信します。複数のデータを放出できるパイプのようなものだと考えてください。イベント、リアルタイムの更新、またはデータを少しずつ処理するのに最適です。
Stream.fromIterable() や、async* と yield を使用した非同期ジェネレータ関数を使用して、シンプルなストリームを作成できます:
Stream<int> countToThree() async* {
yield 1;
yield 2;
yield 3;
}
Future<void> main() async {
await for (var number in countToThree()) {
print(number);
}
}
// 出力: 1, 2, 3async*キーワードは、Streamを返す関数を定義する際に使用し、yieldは各値を送出します。ストリームを処理するには、値が届くたびに順次処理を行うawait forを使用します。
また、コールバック関数を引数に取る listen() メソッドを使用して、ストリームをリッスンすることもできます。
Stream<String> greetings() async* {
yield 'Hello';
yield 'Hi';
yield 'Hey';
}
void main() {
greetings().listen((message) {
print(message);
});
}Futureとの主な違いは、Futureは単一の値で一度だけ完了するのに対し、Streamは終了するまでに多くの値を放出できる点です。これにより、Streamはユーザーの操作、センサーの読み取り、または細切れに届くデータなどの継続的なデータを扱うのに理想的です。
チャレンジ
簡単ストリームを使用して、時間の経過とともに値を放出するカウントダウンタイマーシステムを構築しましょう!カウントダウン数値のシーケンスを生成するクラスを作成し、ストリームが単一の値ではなく複数の値をどのように配信するかを学びます。
コードを2つのファイルに整理します:
countdown.dart: カウントダウンストリームを生成するCountdownクラスを作成します。クラスには以下を含める必要があります:- カウントダウンの開始数値を格納する
startフィールド (int) - 開始数値を受け取るコンストラクタ
Stream<int>を返すcountDown()メソッド。async*とyieldを使用して、startから0(0を含む)までの数値を放出しますStream<String>を返すcountDownWithMessage()メソッド。これは、startから1までの各数値に対して'T-minus [number]'という形式の文字列を放出し、最後に'Liftoff!'を放出します
- カウントダウンの開始数値を格納する
main.dart: カウントダウンファイルをインポートし、両方のストリームメソッドを実演します。main関数は async である必要があり、以下の処理を行います:3から始まるCountdownインスタンスを作成します'Number countdown:'とプリントしますawait forを使用してcountDown()を反復処理し、各数値をプリントします- 空行をプリントします
'Launch sequence:'とプリントしますawait forを使用してcountDownWithMessage()を反復処理し、各メッセージをプリントします
各 yield ステートメントがストリームを通じて値を放出し、await for が到着した各値を処理する様子に注目してください。1つの結果を配信する Future とは異なり、ストリームは複数の値を順番に放出します!
期待される出力:
Number countdown:
3
2
1
0
Launch sequence:
T-minus 3
T-minus 2
T-minus 1
Liftoff!チートシート
Streamは、単一の値を返すFutureとは異なり、時間の経過とともに一連の値を配信します。ストリームは、イベント、リアルタイムの更新、またはデータを少しずつ処理するのに最適です。
async*とyieldを使用した非同期ジェネレータ関数を使用してストリームを作成します:
Stream<int> countToThree() async* {
yield 1;
yield 2;
yield 3;
}await forを使用してストリームを処理します:
Future<void> main() async {
await for (var number in countToThree()) {
print(number);
}
}または、コールバックを指定してlisten()メソッドを使用します:
void main() {
greetings().listen((message) {
print(message);
});
}Stream.fromIterable()を使用して、イテラブルからストリームを作成することもできます。
自分で試してみよう
import 'countdown.dart';
Future<void> main() async {
// TODO: 3から始まるCountdownインスタンスを作成する
// TODO: 'Number countdown:' を出力する
// TODO: await forを使用してcountDown()を反復処理し、各数値を出力する
// TODO: 空行を出力する
// TODO: 'Launch sequence:' を出力する
// TODO: await forを使用してcountDownWithMessage()を反復処理し、各メッセージを出力する
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
4Null Safety
Null Safety 入門Nullable と Non-Nullable? 演算子と ! 演算子late キーワードと Null SafetyNull-Aware 演算子クラスにおける Null Safetyまとめ:ユーザープロフィールシステム10コレクションとジェネリクス
List, Set, Map の概要型安全なコレクションジェネリッククラスジェネリックメソッドジェネリクスの制約Iterable と Iteratorまとめ:ジェネリックなストレージ