狐好きぷろぐらまー

狐好きプログラマーのブログです。

【Dart】rxdartについて調べてみる 第7回目 -RetryWhen, SequenceEqual- 【rxdart】

こんにちは。 pregum_foxです。

今回は、RetryWhenオペレータとSequenceEqualオペレータについて調べました。

前回までの記事は以下をご覧ください。

動作環境

動作環境は以下の通りです。

項目 バージョン
Dart 2.5.1
rxdart 0.22.2

いかにRetryWhenオペレータとSequenceEqualオペレータについて記載します。 オペレータの名称はRx、rxdart、Stream APIの順で記載します。

RetryWhenオペレータ

Rxには、Retryオペレータのみコアのオペレータ扱いで、RetryWhenオペレータは言語によって実装されていたりいなかったりするみたいです。

シグネチャ

  • rxdart
    Observable<T> Observable<T>.retryWhen(Stream<T> streamFactory(), Stream<void> retryWhenFactory(dynamic error, StackTrace stack))

  • Stream API
    RetryWhenStream<T>(Stream<T> streamFactory(), Stream<void> retryWhenFactory(dynamic error, StackTrace stack))

処理の概要

購読された時にstreamFactory()を実行し、Streamを作成し発行します。
正常に終了するか、エラーを出力するとStreamは終了します。 streamFactory()処理内で、エラーが出力された場合、retryWhenFactory()の処理が実行されます。
その後エラー処理をしなかった場合、エラーがretryWhenFactory()外に出力されます。
以下にサンプルを示します。

/// rxdartのRetryWhenオペレータサンプル
void studyRetryWhen() {
  Observable<int>.retryWhen(
      () => Observable<int>.periodic(Duration(seconds: 1), (i) => (i))
          .map((i) => i == 2 ? throw 'exception' : i),
           (e, s) {
    print('error catch. ');
    return Observable<String>.timer(
        'random value', Duration(milliseconds: 200));
  }).take(4).listen(print);
}
// 実行結果
// 0
// 1
// error catch.
// 0
// 1
  
/// Stream APIのRetryWhenオペレータサンプル
void studyRetryWhenStream() {
  RetryWhenStream<int>(
      () => Stream<int>.periodic(Duration(seconds: 1), (i) => i)
          .map((i) => i == 2 ? throw 'exception' : i), (e, s) {
    print('error catch. ');
    return TimerStream<String>('random value', Duration(milliseconds: 200));
  }).take(4).listen(print);
}
// 実行結果
// 0
// 1
// error catch.
// 0
// 1

サンプルの実行結果から、第1引数のstreamFactory()内でStreamが作成、発行されています。
エラーが発生した場合、第2引数のretryWhenFactory(dynamic error, StackTrace stack)内でエラーハンドリングされています。
その後再度streamFActory()内に戻った時には、前の値は保持されておらず、初期値のStreamが出力されています。

SequenceEqualオペレータ

シグネチャ

  • rxdart Observable<bool> Observable<bool>.sequenceEqual<A, B>(Stream<A> stream, Stream<B> other, {bool equals(A a, B b)})

  • Stream API SequenceEqualStream<S, T>(Stream<S> stream, Stream<T> other, {bool equals(S s, Tt) })

処理の概要

2つのStreamが同じシーケンスを発行するかどうかを判断します。
オプションのequalsを使用して同等性を判断できます。
以下にサンプルを示します。

/// rxdartのSequenceEqualオペレータサンプル
void studySequenceEqual() {
  Observable.sequenceEqual(Observable.fromIterable([1, 2, 3, 4, 5]),
      Observable.fromIterable([1, 2, 3, 4, 5])).listen(print);

  Observable.sequenceEqual(Observable.fromIterable([1, 2, 3, 4, 5]),
      Observable.fromIterable([1, 2, 3, 4])).listen(print);
}
// 実行結果
// false
// true
  
/// Stream APIのSequenceEqualオペレータサンプル
void studySequenceEqualStream() {
  SequenceEqualStream(Stream.fromIterable([1, 2, 3, 4, 5]),
      Stream.fromIterable([1, 2, 3, 4, 5])).listen(print);

  SequenceEqualStream(Stream.fromIterable([1, 2, 3, 4, 5]),
      Stream.fromIterable([1, 2, 3, 4])).listen(print);
}
// 実行結果
// false
// true

サンプルの実行結果から、シーケンスが一致しているかどうか判断できていることが確認できます。

参考サイト