web-dev-qa-db-ja.com

RxJava doOnErrorとonErrorReturnはどのように機能しますか?

私はこれらの単体テストを行いましたが、結果は期待したものではありませんでした。

// This one outputs "subscribe.onError" 
@Test
public void observable_doOnError_subscribingToError() throws InterruptedException {
    Observable<String> obs = getErrorProducingObservable();
    obs.doOnError(throwable -> System.out.println("doOnError"));
    obs.subscribeOn(Schedulers.immediate()).observeOn(Schedulers.immediate()).subscribe(
        s -> {},
        error -> System.out.println("subscribe.onError")
    );
    Thread.sleep(300);
}

// This one outputs "subscribe.onError" 
@Test
public void observable_onErrorReturn() throws InterruptedException {
    Observable<String> obs = getErrorProducingObservable();
    obs.onErrorReturn(throwable -> "Yeah I got this");
    obs.subscribeOn(Schedulers.immediate()).observeOn(Schedulers.immediate()).subscribe(
        s -> System.out.println("got: " + s),
        error -> System.out.println("subscribe.onError")
    );
    Thread.sleep(300);
}

private Observable<String> getErrorProducingObservable()  {
    return Observable.create(subscriber -> {
        subscriber.onError(new RuntimeException("Somebody set up us the bomb"));
    });
}

したがって、両方の出力 "subscribe.onError"-doOnErroronErrorReturnも呼び出されていないようです。

doOnErrorは次のように文書化されています:

OnErrorを呼び出した場合にアクションを呼び出すように、ソースObservableを変更します。

どう解釈するのかわかりませんが、「doOnError」が出力されるか、「doOnError」の後に「subscribe.onError」が続くと予想しました。

onErrorReturnは次のように文書化されています:

エラーが発生した場合にonErrorを呼び出すのではなく、アイテム(指定された関数によって返される)を発行するようにObservableに指示します。

したがって、後者のテストからの出力として、「得た:ええ、これを得た」と期待していました。

何が得られますか?

20
Nilzor

doOnErroronErrorReturnは両方とも、動作が変更された新しいObservableを返します。それらの文書が少し誤解を招くかもしれないことに同意します。次のようにテストを変更して、予想される動作を取得します。

// This one outputs "subscribe.onError" 
@Test
public void observable_doOnError_subscribingToError() throws InterruptedException {
    Observable<String> obs = 
        getErrorProducingObservable()
            .doOnError(throwable -> System.out.println("doOnError"));

    obs.subscribeOn(Schedulers.immediate()).observeOn(Schedulers.immediate()).subscribe(
        s -> {},
        error -> System.out.println("subscribe.onError")
    );
    Thread.sleep(300);
}

// This one outputs "subscribe.onError" 
@Test
public void observable_onErrorReturn() throws InterruptedException {
    Observable<String> obs = 
        getErrorProducingObservable()
            .onErrorReturn(throwable -> "Yeah I got this");

    obs.subscribeOn(Schedulers.immediate()).observeOn(Schedulers.immediate()).subscribe(
        s -> System.out.println("got: " + s),
        error -> System.out.println("subscribe.onError")
    );
    Thread.sleep(300);
}

private Observable<String> getErrorProducingObservable()  {
    return Observable.create(subscriber -> {
        subscriber.onError(new RuntimeException("Somebody set up us the bomb"));
    });
}
16
marstran