RxJava2の話です。
自分でSingle.create した時についうっかりonSuccessしたあとにonErrorを実行するようなコードを書いた場合どうなるのだろうか?と思ったのでやってみました。
Single<String> single = Single.create(emitter -> { emitter.onSuccess("test"); emitter.onError(new RuntimeException("エラー")); }); single.subscribe(string -> { Log.i("TEST", string); }, throwable -> { Log.i("TEST", "onError"); });
こういうコードだとUndeliverableExceptionが出る。UndeliverableExceptionなので当然onErrorは実行されない。
では、onSuccessが2回実行されたらUndeliverableExceptionが出るのかと思ったけど、そうではないみたい。
以下のコードは 最初のonSuccessが1度実行されて終わる。
Single<String> single = Single.create(emitter -> { emitter.onSuccess("test"); emitter.onSuccess("hoge"); }); single.subscribe(string -> { Log.i("TEST", string); }, throwable -> { Log.i("TEST", "onError"); });
これを読んでると single()
はonSuccessが2回実行されると死ぬでと書いてるのでRxJava2ではどうなのか確認してみたところ、RxJava2でも同様にエラーになったので同じく2つ目以降の値は流れてきてはいけないものに使うと認識した。
Observable.range(1, 5).single(100).subscribe(i -> { Log.i("TEST", String.valueOf(i)); }, Throwable::printStackTrace);
1個で良い場合は、first()
を使うとよさそうだった。
Observable.range(1, 5).first(100).subscribe(i -> { Log.i("TEST", String.valueOf(i)); }, Throwable::printStackTrace);
追記:
紛らわしい感じだったので、タイトル直した。
複数回呼ばないほうが安心安全っぽいので基本はそうするのが良さそう
いえいえ。ちなみに、契約として Single のイベントは onSuccess か onError が1度しか来ないはずなので、いまのような挙動になっているようですね。Emitter で複数回 onSuccess/onError はあまり呼ばない方が良さそうです。
— Hiroshi Kurokawa (@hydrakecat) 2017年8月24日