パルカワ2

PerlとRubyとイチャラブ

io.reactivex.Single.create() でonSuccessしたあとにonErrorを実行するように書いたらどうなるのか

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");
});

qiita.com

これを読んでると 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);

追記:
紛らわしい感じだったので、タイトル直した。
複数回呼ばないほうが安心安全っぽいので基本はそうするのが良さそう