RxJava基础五-错误处理操作符

此篇内容均是来自书籍《RxJava响应式编程》李衍顺 著

3.5 错误处理操作符

RxJava对错误的处理很方便,当有错误的时候就会调用Subscriber的onError方法将错误分发出去,由Subscriber自己来处理错误。这种处理错误的方式虽然方便,但也有缺点,就是每个Subscriber都要去定义如何处理错误,如果有100个Subscriber,就要定义100遍。这节来学习如何用错误处理操作符来集中处理错误。

3.5.1 onErrorReturn

onErrorReturn 操作符可在发生错误时,让Observable发送一个预先定义好的数据并停止继续发送数据。

/**
     * onErrorReturn
     */
    private Observable createObserver() {
        return Observable.create(new Observable.OnSubscribe(){

            @Override
            public void call(Subscriber subscriber) {
                for(int i= 1; i<=6; i++){
                    if(i<3){
                        subscriber.onNext("onNext:" + i);
                    } else {
                        subscriber.onError(new Throwable("Throw error"));
                    }
                }
            }
        });
    }
    private Observable onErrorReturnObserver(){
        return createObserver().onErrorReturn(new Func1() {
            @Override
            public String call(Throwable throwable) {
                return "onErrorReturn";
            }
        });
    }
    private void onErrorReturnTest(){
        onErrorReturnObserver().subscribe(new Subscriber() {
            @Override
            public void onCompleted() {
                log("onErrorReturn-onCompleted");
            }

            @Override
            public void onError(Throwable e) {
                log("onErrorReturn-onError:" + e.getMessage());
            }

            @Override
            public void onNext(String s) {
                log("onErrorReturn-onNext:" + s);
            }
        });
    }
输出结果:
在发送出两个数据之后, onErrorReturn捕捉到了抛出的异常并返回了指定的字符串给订阅者,然后整个Observable发送数据的过程结束。
onErrorReturn-onNext:onNext:1
onErrorReturn-onNext:onNext:2
onErrorReturn-onNext:onErrorReturn
onErrorReturn-onCompleted

3.5.2 onErrorResumeNext

onErrorReturn操作符在有错误事件的时候回让Observable停止发送数据;而onErrorResumeNext在有错误发送的时候,会创建另外一个Observable来代替当前的Observable并继续发送数据,就好像错误并没有发生一样。

private Observable createObserver() {
        return Observable.create(new Observable.OnSubscribe(){

            @Override
            public void call(Subscriber subscriber) {
                for(int i= 1; i<=6; i++){
                    if(i<3){
                        subscriber.onNext("onNext:" + i);
                    } else {
                        subscriber.onError(new Throwable("Throw error"));
                    }
                }
            }
        });
    }
private Observable onErrorReturnObserver(){
        return createObserver().onErrorReturn(new Func1() {
            @Override
            public String call(Throwable throwable) {
                return "onErrorReturn";
            }
        });
    }
    private void onErrorReturnTest(){
        onErrorReturnObserver().subscribe(new Subscriber() {
            @Override
            public void onCompleted() {
                log("onErrorReturn-onCompleted");
            }

            @Override
            public void onError(Throwable e) {
                log("onErrorReturn-onError:" + e.getMessage());
            }

            @Override
            public void onNext(String s) {
                log("onErrorReturn-onNext:" + s);
            }
        });
    }
订阅输出结果如下,在正常发送两个数据后产生错误,新创建的Observable继续发送7、8、9三个数字,然后整个数据发送过程结束
onErrorResumeNext-onNext:onNext:1
onErrorResumeNext-onNext:onNext:2
onErrorResumeNext-onNext:7
onErrorResumeNext-onNext:8
onErrorResumeNext-onNext:9
onErrorResumeNext-onCompleted

3.5.3 onExceptionResumeNext

onExceptionResumeNext操作符类似于onErrorResumeNext,不同之处在于其会对onError抛出的数据类型做判断--如果是Exception, 就会使用另一个Observable代替原Observable继续发送数据,否则将错误分发给Subscriber。

/**
     * onExceptionResumeNext
     */
    private Observable createObserver(final Boolean createException) {
        return Observable.create(new Observable.OnSubscribe() {
            @Override
            public void call(Subscriber subscriber) {
                for(int i=1; i<=6; i++){
                    if(i<3){
                        subscriber.onNext("onNext:" + i);
                    } else if(createException){
                        subscriber.onError(new Exception("Exception"));
                    } else {
                        subscriber.onError(new Throwable("Throw error"));
                    }
                }
            }
        });
    }
    private Observable onExceptionResumeObserver(boolean isException) {
        return createObserver(isException).onExceptionResumeNext(Observable.just("7","8","9"));
    }
    private void onExceptionResumeNextTest(){
        onExceptionResumeObserver(true).subscribe(new Subscriber() {
            @Override
            public void onCompleted() {
                log("onException-true-onCompleted");
            }

            @Override
            public void onError(Throwable e) {
                log("onException-true-onError:" + e.getMessage());
            }

            @Override
            public void onNext(String s) {
                log("onException-true-onNext:" + s);
            }
        });

        onExceptionResumeObserver(false).subscribe(new Subscriber() {
            @Override
            public void onCompleted() {
                log("onException-false-onCompleted");
            }

            @Override
            public void onError(Throwable e) {
                log("onException-false-onError:" + e.getMessage());
            }

            @Override
            public void onNext(String s) {
                log("onException-false-onNext:" + s);
            }
        });
    }
输出的结果如下,当错误的类型是Exception时, 在发送完1和2之后,onExceptionResumeNext会捕获到错误事件并且用新的Observable来继续发送数据7,8,9,最后整个过程正常结束;而当错误类型不是Exception时,onExceptionResumeNext将不会起任何作用,错误事件被直接分发给订阅者,整个过程非正常结束
onException-true-onNext:onNext:1
onException-true-onNext:onNext:2
onException-true-onNext:7
onException-true-onNext:8
onException-true-onNext:9
onException-true-onCompleted
onException-false-onNext:onNext:1
onException-false-onNext:onNext:2
onException-false-onError:Throw error

3.5.4 retry

retry操作符在发送错误时会重新进行订阅, 而且可以重复多次,所以发送的数据可能会产生重复。但是有可能每次retry都会发送错误,从而造成不断订阅不断retry的死循环,这种情况下可以指定最大重复次数。如果retry达到了最大重复次数还有错误的话,就将错误返回给观察者。

/**
     * retry
     */
    private Observable createRetryObserver(){
        return Observable.create(new Observable.OnSubscribe() {
            @Override
            public void call(Subscriber subscriber) {
                log("subscribe");
                for(int i=0; i<3; i++){
                    if(i==2){
                        subscriber.onError(new Exception("Exception"));
                    } else {
                        subscriber.onNext(i);
                    }
                }
            }
        });
    }
    private void retryTest(){
        createRetryObserver().retry(2).subscribe(new Subscriber() {
            @Override
            public void onCompleted() {
                log("retry-onCompleted");
            }

            @Override
            public void onError(Throwable e) {
                log("retry-onError:"+ e.getMessage());
            }

            @Override
            public void onNext(Integer integer) {
                log("retry-onNext:" + integer);
            }
        });
    }
输出结果如下,Observable每次发送两个数据后会发送错误事件,从而导致重新订阅,在重新订阅了两次后, 错误事件最终被分发给了订阅者。
subscribe
retry-onNext:0
retry-onNext:1
subscribe
retry-onNext:0
retry-onNext:1
subscribe
retry-onNext:0
retry-onNext:1
retry-onError:Exception

你可能感兴趣的:(RxJava基础五-错误处理操作符)