LoginSignup
6
5

More than 5 years have passed since last update.

ReactiveExtensionsでstreamを分割する

Last updated at Posted at 2015-12-22

この記事はモバイルファクトリー Advent Calendar 22日目の記事です。

昨日は@morigamixさんのMaterial Designに従ってリスト周りのUIを考えてみたでした。

今日は@yashims85がお送りします。

前提

  • RxJavaとKotlinを使って今回はお話させて頂きます。

突然ですが問題です

val subject = PublishSubject.create<Int>()
val stream = subject.doOnNext {
    Log.d("yashims85", "value ${it.toString()} on stream")
}
stream.filter({ it > 10 }).subscribe {
    Log.d("yashims85", "${it.toString()} is bigger then 10")
}
stream.filter({ it % 4 == 0 }).subscribe {
    Log.d("yashims85", "${it.toString()} surplus 4 is zero")
}
subject.onNext(12)

上記のコードからは共通のstreamを
* メッセージが10より大きければ流れるstream
* メッセージが4で割り切れたら流れるstream

の2つに分割したい意図が感じ取れますが、共通部分のvalue 12 on streamは何回出力されるでしょうか?

答え

結果
12-22 14:39:39.654 22766-22766/? D/yashims85: value 12 on stream
12-22 14:39:39.654 22766-22766/? D/yashims85: 12 is bigger then 10
12-22 14:39:39.654 22766-22766/? D/yashims85: value 12 on stream
12-22 14:39:39.654 22766-22766/? D/yashims85: 12 surplus 4 is zero

というわけで2回出力されてしましました。これはobservableのチェーンがsubscribe毎に作られるためです。

しかし、本来は共通部分は1回だけ処理して欲しところですね。。。

そんな時役立つのが、Observable.share()です。

Observable.share

上流のObservableをHot変換し、上流から来たデータを流す別のObservableを下流に提供します。
また、shareで生成されたObservableをObserveする人がいなくなると、上流のObserveも停止します。

つまりは、share()の戻り値のObservableは上流のObservableとは別物なので、streamを共通化出来ます。

試してみよう

share()を追加してみる

val subject = PublishSubject.create<Int>()
val stream = subject.doOnNext {
    Log.d("yashims85", "value ${it.toString()} on stream")
}.share()
stream.filter({ it > 10 }).subscribe {
    Log.d("yashims85", "${it.toString()} is bigger then 10")
}
stream.filter({ it % 4 == 0 }).subscribe {
    Log.d("yashims85", "${it.toString()} surplus 4 is zero")
}
subject.onNext(12)

最初のコードのdoOnNextの後にshare()を追加しただけです。
さて、結果はどうなるでしょうか?

結果
12-22 14:52:04.414 9325-9325/? D/yashims85: value 12 on stream
12-22 14:52:04.414 9325-9325/? D/yashims85: 12 is bigger then 10
12-22 14:52:04.414 9325-9325/? D/yashims85: 12 surplus 4 is zero

はい!共通化できました!

まとめ

streamを分割したい時はshareするとよい。

明日の担当は、採用担当でジンジニアの二つ名を持つjinjineerさんです。わたし気になります!

6
5
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
5