【 Flutter 】Flutter を 基礎 から 学習 ( Dart編 ) part32 Dartの特徴
「基礎 から 学ぶ Flutter 」という書籍で 学習 したことを ブログでアウトプットしていこうと思います。今回は Dart編 ( part32 )です。
前回
【 Flutter 】Flutter を 基礎 から 学習 ( Dart編 ) part31 Dartの特徴
今回はStream
についての学習です。
Dartの特徴
Stream
リアクティブプログラムの基礎です。
リアクティブプログラムというのはデータを受け取るたびに関連したプログラムが反応(リアクション)して処理を行うようにするプログラミングの考え方です。
C#のRx(リアクティブエクステンション)がリアクティブプログラムを実現するものになるでしょうか。
Stream
はFuture
のように成功、失敗を非同期で取得可能です。
Future
は値を取得すると処理が終わりますがStream
は閉じないと(遮断しないと)ずっと値が流れ込んできます。
動かして理解する!dartのStreamとrxdart! – Qiita
発行する側と購読する側があって、発行する側が「ぽいっ」ってデータを投げると購読する側が検知して、なんらかの処理をする。そんな感じのイメージです。
上記のサイトで紹介されているサンプルコードを少し改良してみました。
※本書のサンプルコードがどんどん雑なものになってきているように感じます。
import 'dart:async';
var controller = StreamController();
// async/awaitについては別の章で説明があります。
// この時点では私は見よう見まねで実装しているだけです。
void main() async {
// listenさせます(購読する)
var subscription = koudokusya1();
// streamを流します。(購読している人へ新聞配達する感じ)
controller.sink.add('新聞だょ〜(´・ω・`)b');
await Future.delayed(Duration(seconds: 2));
controller.sink.add('今日の夕刊新聞だょ〜(´・ω・`)b');
await Future.delayed(Duration(seconds: 2));
subscription.cancel();
controller.close();
}
StreamSubscription koudokusya1() {
var subscription = controller.stream.listen((data){
print('購読している人1');
print(data);
});
return subscription;
}
実行するとこうなります。
うまく伝わらないかもしれせんがsink.add
する度にcontroller.stream.listen
に渡した関数が実行されています。
C#よりもすごくお手軽な感じが良いですね。
StreamController
クラスはdart:async
を読み込んでおかないと使用できません。
listen
するとStreamSubscription
オブジェクト(購読する人)が1つ生成されます。
複数の購読を行う場合はasBroadcastStream()
を使用します。
import 'dart:async';
var controller = StreamController();
// async/awaitについては別の章で説明があります。
// この時点では私は見よう見まねで実装しているだけです。
void main() async {
// listenさせます(購読する)
var subscription = koudokusya1();
// streamを流します。(購読している人へ新聞配達する感じ)
controller.sink.add('新聞だょ〜(´・ω・`)b');
await Future.delayed(Duration(seconds: 2));
controller.sink.add('今日の夕刊新聞だょ〜(´・ω・`)b');
await Future.delayed(Duration(seconds: 2));
subscription.cancel();
controller.close();
}
StreamSubscription koudokusya1() {
// どうやって利用するの?
var subscription = controller.stream.asBroadcastStream().listen((data){
print('購読している人1');
print(data);
});
return subscription;
}
購読を終了させたい場合はStreamSubscription
クラスのcancel()
を呼びます。
pause()
で停止、resume()
で再開したりできます。
他にもエラーの場合はonError
,処理が完了したときに呼ばれるonDone
、エラーになっていもキャンセル(購読終了)させないようにするcancelOnError
プロパティがあります。
コレクション同様map()
やwhere()
を使って流れてくるデータを加工・制限することも可能です。
この辺りはJavaのStreamに似ていますね。というかそのままですね!
import 'dart:async';
var controller = StreamController();
// async/awaitについては別の章で説明があります。
// この時点では私は見よう見まねで実装しているだけです。
void main() async {
// listenさせます(購読する)
var subscription = koudokusya1();
// streamを流します。(購読している人へ新聞配達する感じ)
controller.sink.add('新聞だょ〜(´・ω・`)b');
await Future.delayed(Duration(seconds: 2));
controller.sink.add('今日の夕刊新聞だょ〜(´・ω・`)b');
await Future.delayed(Duration(seconds: 2));
subscription.cancel();
controller.close();
}
StreamSubscription koudokusya1() {
// 夕刊が不要なのでデータを流さない
// さらに流れてきたデータの末尾に文字を付加する
var subscription = controller.stream
.where((data) => !data.contains('夕刊') )
.map((data) => data + ' by なぞなぞ新聞')
.listen((data){
print('購読している人1');
print(data);
});
return subscription;
}
最後に
リアクティブは「考え方」が重要です。「データを取りに行く」ではなく「データが来る」という意識をもって実装するとよいと思いました。
今日はここまで!
ディスカッション
コメント一覧
まだ、コメントがありません