こんにちは。pregum_foxです。
前回から3年ほど開いて、rxdartのバージョンも0.27.7になりましたが、久しぶりに書いていきたいと思います。
みたところ0.23.x以降は大きな変更はないみたいなので、とりあえず最新バージョンで色々書いていきます。
今回は、concatWithとdebounceについてです。
今までの一覧は下記記事に記載しています。
目次です。
動作環境
動作環境は以下の通りです。
項目 | バージョン |
---|---|
dart | 3.0.6 |
rxdart | 0.27.7 |
以下にconcatWithオペレータとdebounceオペレータについて気足します。 名称はRx、rxdart、Stream APIの順で記載していきます。
concatWithオペレータ
- Rx: concat
- rxdart: concatWith メソッド
- Steam API: 厳密にはなし( concatStream
クラスが近い)
シグネチャ
- rxdart
Stream<T> concatWith(Iterable<Stream<T>> other)
- Stream API
ConcatStream<T> ConcatStream(Iterable<Stream<T>> streams)
処理の概要
引数に渡されたStreamを順番に出力します。
import 'package:rxdart/rxdart.dart'; Future studyConcatWith() async { // 1のstreamを発行 Stream.value(1) // 複数のstreamを順番に追加していく .concatWith([ // 0~4までのstreamを発行 Stream.periodic(Duration(milliseconds: 100), (int i) => i).take(5), // 5~9までのstreamを発行 Stream.periodic(Duration(milliseconds: 100), (int i) => i).skip(5).take(5), ]).listen(print, onDone: () => print('on done.')); } // ===実行結果=== // 1 // 0 // 1 // 2 // 3 // 4 // 5 // 6 // 7 // 8 // 9 // on done.
debounceオペレータ
- Rx: Debounce
- rxdart: debounce メソッド
- Stream API: DebounceStreamTransformer
クラス
シグネチャ
- rxdart
Stream<T> debounce(Stream Function(T event) window)
- Stream API
DebounceStreamTransformer<T> DebounceStreamTransformer(Stream Function(T event) window)
処理の概要
引数に渡されたイベントの最後の発行から指定した期間経った後、その時最後に渡されているイベントを次のオペレータに渡します。
言葉だと分かりにくいと思うのでサンプルコードをみて下さい。
import 'package:rxdart/rxdart.dart'; Future studyDebounce() async { // 500ms毎にカウントアップするストリームを生成する Stream.periodic(Duration(milliseconds: 500), (int i) => i) // 値発行から300ms後にイベントを発火する .debounce((event) { print('debounde: $event'); return TimerStream(true, Duration(milliseconds: 300)); }) // 5要素取得する .take(5) .listen(print, onDone: () => print('on done.')); // 区切る為に少し待つ await Future.delayed(const Duration(milliseconds: 3000)); print('--------------------------------------------------'); // 100ms毎にカウントアップするストリームを生成する Stream.periodic(Duration(milliseconds: 100), (int i) => i) // 5要素取得する .take(5) // この場合、300ms経つ前に次の値が先に来る為、フィルタされる .debounce((event) { print('debounde: $event'); return TimerStream(true, Duration(milliseconds: 300)); }).listen(print, onDone: () => print('on done.')); // 区切る為に少し待つ await Future.delayed(const Duration(milliseconds: 4000)); print('--------------------------------------------------'); // 100ms毎にカウントアップするストリームを生成する Stream.periodic(Duration(milliseconds: 100), (int i) => i) // 5要素取得する .take(5) // 偶数のみ通す .debounce( (event) { print('debounde: $event, isEven: ${event.isEven}'); if (event.isEven) { // trueでなくてもとりあえず値を返せば良い return Stream.value(true); } else { // 値は返さないといけないので、実質無限に遅延するStreamを返す return TimerStream(true, Duration(days: 99999)); } }, ).listen(print, onDone: () => print('on done.')); } // ===実行結果=== // debounde: 0 // 0 // debounde: 1 // 1 // debounde: 2 // 2 // debounde: 3 // 3 // debounde: 4 // 4 // on done. // -------------------------------------------------- // debounde: 0 // debounde: 1 // debounde: 2 // debounde: 3 // debounde: 4 // 4 // on done. // -------------------------------------------------- // debounde: 0, isEven: true // 0 // debounde: 1, isEven: false // debounde: 2, isEven: true // 2 // debounde: 3, isEven: false // debounde: 4, isEven: true // 4 // on done.
雑感
3年ぶりに書いてみましたが、一覧があってどこから書いていけば良いかすぐわかったので、このままの勢いで月二ぐらいのペースでかけると良いなと思います。
ここまで読んで頂き、ありがとうございました。