ひよっこゲームブログ

なにもかも初心者のひよっこがゆったりと何かする

リアクティブプログラミング7日目

今日もRxJavaのリファレンス読む

Continuations

和訳で「継続」


Dependent

和訳で「依存」

itemが利用可能になったとき、それに依存する計算をしたい
これをContinuationsと呼ぶ

最も一般的なパターンは
値を指定して別のサービスを呼び出し、結果を受け取って処理を継続するとか

サンプルコード

service.apiCall()
.flatMap(value -> service.anotherApiCall(value))
.flatMap(next -> service.finalCall(next))

サンプルコード見た感じだとまぁ見たまんまの処理


flatMapの中にflatMapを入れるみたいな場合

サンプルコード

service.apiCall()
.flatMap(value ->
    service.anotherApiCall(value)
    .flatMap(next -> service.finalCallBoth(value, next))
)

これもシンプルに見たまんまの処理


Non-dependent

和訳で「非依存」

原文読んでもピンとこなかったので読み解いてみる

サンプルコード(ダメなパターン)

Observable continued = sourceObservable.flatMapSingle(ignored -> someSingleSource)
continued.map(v -> v.toString())
  .subscribe(System.out::println, Throwable::printStackTrace);
  • flatMapSingle
    Flowableの各要素をSingleSourceにしてマッピングする
    Single = 値かエラーが1度だけ流れる

今までと違うところは、observableの宣言をしてflatMap
そのあとにmapで整頓してる

1回ずつoperatorを使いたいって感じ

この場合だとoperatorの処理でマッピングが複数の値をもたらす可能性があるみたい
んー、なぜだ?

あー・・・?
値が入り次第、次のmapが動作しちゃうみたい

こっちの方法で書くのが正解

andThenを利用することで、前のobservableが正常完了してから次のobservableが動作する
なるほど

サンプルコード

sourceObservable
  .ignoreElements()           // returns Completable
  .andThen(someSingleSource)
  .map(v -> v.toString())


Deferred-dependent

和訳で「遅延依存」

前と後ろでデータ依存があり
何らかの理由で「通常のチャンネル」をストリームしていない場合

サンプルコード(ダメなパターン)

AtomicInteger count = new AtomicInteger();

Observable.range(1, 10)
  .doOnNext(ignored -> count.incrementAndGet())
  .ignoreElements()
  .andThen(Single.just(count.get()))
  .subscribe(System.out::println);

これは全て「0」が出力されてしまう
Single.just(count.get()) がデータフロー実行前に評価されてしまうのでアウト

よってメインのストリームが終わってから評価する必要がある
=遅延依存


サンプルコード

AtomicInteger count = new AtomicInteger();

Observable.range(1, 10)
  .doOnNext(ignored -> count.incrementAndGet())
  .ignoreElements()
  .andThen(Single.defer(() -> Single.just(count.get())))
  .subscribe(System.out::println);

または

AtomicInteger count = new AtomicInteger();

Observable.range(1, 10)
  .doOnNext(ignored -> count.incrementAndGet())
  .ignoreElements()
  .andThen(Single.fromCallable(() -> count.get()))
  .subscribe(System.out::println);


あー、これは忘れたころにつまずきそうなパターンだ・・・


今日やった部分はデータフローの仕方がごちゃっとしてるなぁ(体感)
とりまここまで、おやすみなさーい