Android从零开始学习Rxjava2(八)—— 错误处理运算符

错误处理运算符

有助于从Observable中恢复错误通知的操作符。Rx错误处理有两个类别的运算符:

Catch类:Catch运算符拦截来自源Observable的onError通知,而不是将其传递给任何观察者,将其替换为其他项目或项目序列,可能允许生成的Observable正常终止或根本不终止;

Retry类:如果源Observable发出错误,请重新订阅它,希望它能完成而不会出错。重试操作符通过不将该调用传递给其观察者来响应来自源Observable的onError通知,而是通过重新订阅源Observable并为其提供另一个机会来完成其序列而不会出现错误。 重试始终将下一个通知传递给其观察者,即使是以错误终止的序列,因此这会导致重复发射

Rx中有几个常见的Catch类的操作符:onErrorReturn,onErrorResumeNext,onExceptionResumeNext。
Rx中也有几个常见的Retry类的操作符:retry,retryWhen。

我们这里来一一看下:

onErrorReturn

指示Observable在遇到错误时发出特定项,然后正常终止。
Catch运算符拦截来自源Observable的onError通知,而不是将其传递给任何观察者,将其替换为其他项目或项目序列,可能允许生成的Observable正常终止或根本不终止。
onErrorReturn运算符,当源Observable发射出onError时,拦截异常并返回一个自定义的值之后正常的结束发射。
举个例子

private void doSomeWork() {
        Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> observableEmitter) throws Exception {
                observableEmitter.onNext("1");
                observableEmitter.onNext("2");
                observableEmitter.onError(new Throwable("error"));
                observableEmitter.onNext("3");
                observableEmitter.onComplete();

            }
        }).onErrorReturn(new Function<Throwable, String>() {
            @Override
            public String apply(Throwable throwable) throws Exception {
                Log.d(TAG, " apply : " + throwable.getMessage());
                return "onErrorReturn";
            }
        }).subscribe(new Observer<String>() {
            @Override
            public void onSubscribe(Disposable disposable) {

            }

            @Override
            public void onNext(String s) {
                Log.d(TAG, " onNext : s : " + s);
            }

            @Override
            public void onError(Throwable throwable) {
                Log.d(TAG, " onError : " + throwable.getMessage());
            }

            @Override
            public void onComplete() {
                Log.d(TAG, " onComplete ");
            }
        });
    }

当源发射2后发射了error,会先触发onErrorReturn里的方法,所以打印了error,onErrorReturn拦截并通过Func返回一个值后正常结束发射,所以打印结果

onNext : s : 1
onNext : s : 2
apply : error
onNext : s : onErrorReturn
onComplete 

onErrorResumeNext

源Observable在遇到错误时开始发出第二个Observable序列。
在这里插入图片描述
onErrorResumeNext方法与onErrorReturn()方法类似,都是拦截源Observable发射的onError通知。不同的是onErrorReturn拦截并返回一个自定义的值,而onErrorResumeNext拦截并返回一个新的Observable,并继续接收新的Observable发射的数据。

将上方例子稍作更改:

private void doSomeWork() {
        Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> observableEmitter) throws Exception {
                observableEmitter.onNext("1");
                observableEmitter.onNext("2");
                observableEmitter.onError(new Throwable("error"));
                observableEmitter.onNext("3");
                observableEmitter.onComplete();

            }
        }).onErrorResumeNext(new Function<Throwable, ObservableSource<? extends String>>() {
            @Override
            public ObservableSource<? extends String> apply(Throwable throwable) throws Exception {
                Log.d(TAG, " apply : " + throwable.getMessage());
                return Observable.just("new Observable");
            }
        }).subscribe(new Observer<String>() {
            @Override
            public void onSubscribe(Disposable disposable) {

            }

            @Override
            public void onNext(String s) {
                Log.d(TAG, " onNext : s : " + s);
            }

            @Override
            public void onError(Throwable throwable) {
                Log.d(TAG, " onError : " + throwable.getMessage());
            }

            @Override
            public void onComplete() {
                Log.d(TAG, " onComplete ");
            }
        });
    }

打印结果:

onNext : s : 1
onNext : s : 2
apply : error
onNext : s : new Observable
onComplete 

onExceptionResumeNext

指示Observable在遇到异常后继续发出项目(但不是另一种类型的throwable)
在这里插入图片描述
onExceptionResumeNext和onErrorResumeNext类似,不同的是,onExceptionResumeNext如果onError收到的Throwable不是一个Exception,它会将错误传递给观察者的onError方法,不会使用新的Observable。
举个例子

private void doSomeWork() {
        Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> observableEmitter) throws Exception {
                observableEmitter.onNext("1");
                observableEmitter.onNext("2");
                observableEmitter.onError(new Throwable("error"));
//                observableEmitter.onError(new Exception("error"));
                observableEmitter.onNext("3");
                observableEmitter.onComplete();

            }
        }).onExceptionResumeNext(Observable.just("new Observable"))
                .subscribe(new Observer<String>() {
                    @Override
                    public void onSubscribe(Disposable disposable) {

                    }

                    @Override
                    public void onNext(String s) {
                        Log.d(TAG, " onNext : s : " + s);
                    }

                    @Override
                    public void onError(Throwable throwable) {
                        Log.d(TAG, " onError : " + throwable.getMessage());
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG, " onComplete ");
                    }
                });
    }

onError发射的是个非Exception的Error,onExceptionResumeNext不会使用新的Observable,所以打印结果

onNext : s : 1
onNext : s : 2
onError : error

如果将上方例子中此段代码按如下更改

//                observableEmitter.onError(new Throwable("error"));
                observableEmitter.onError(new Exception("error"));

onError发射的是个Exception的Error,打印结果

onNext : s : 1
onNext : s : 2
onNext : s : new Observable
onComplete 

retry

在遇到错误时应尝试重新订阅源Observable。
在这里插入图片描述
retry顾名思义就是重试,遇到Error后让源Observable重新从头发射。
举个例子:

private void doSomeWork() {
        Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> observableEmitter) throws Exception {
                observableEmitter.onNext("1");
                observableEmitter.onNext("2");
                int random = new Random().nextInt(10);
                Log.d(TAG, " subscribe : random : " + random);
                if (random >= 5)
                    observableEmitter.onError(new Throwable("error"));
                observableEmitter.onNext("3");
                observableEmitter.onComplete();

            }
        }).retry(2)
                .subscribe(new Observer<String>() {
                    @Override
                    public void onSubscribe(Disposable disposable) {

                    }

                    @Override
                    public void onNext(String s) {
                        Log.d(TAG, " onNext : s : " + s);
                    }

                    @Override
                    public void onError(Throwable throwable) {
                        Log.d(TAG, " onError : " + throwable.getMessage());
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG, " onComplete ");
                    }
                });
    }

打印结果

onNext : s : 1
onNext : s : 2
subscribe : random : 9
onNext : s : 1
onNext : s : 2
subscribe : random : 8
onNext : s : 1
onNext : s : 2
subscribe : random : 2
onNext : s : 3
onComplete 

retryWhen

在这里插入图片描述
retryWhen和retry类似, 他的区别根据名字也可以知道,他可以让我们控制当xxx时才重试,retryWhen的参数是个Func,我们可以在里面做逻辑处理,如果需要重试,只需要发射一个正常的项即可触发源Observable重试,否则可以发射Error结束。
举个例子:

private void doSomeWork() {
        Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> observableEmitter) throws Exception {
                observableEmitter.onNext("1");
                observableEmitter.onNext("2");
                int random = new Random().nextInt(10);
                Log.d(TAG, " subscribe : random : " + random);
                if (random >= 5)
                    observableEmitter.onError(new Exception("error"));
                observableEmitter.onNext("3");
                observableEmitter.onComplete();

            }
        }).retryWhen(new Function<Observable<Throwable>, ObservableSource<?>>() {
            @Override
            public ObservableSource<?> apply(Observable<Throwable> throwableObservable) throws Exception {
                return throwableObservable.flatMap(new Function<Throwable, ObservableSource<?>>() {
                    @Override
                    public ObservableSource<?> apply(Throwable throwable) throws Exception {
                        if (throwable instanceof Exception)
                            return Observable.just("4");
                        else
                            return Observable.just(throwable);
                    }
                });
            }
        })
                .subscribe(new Observer<String>() {
                    @Override
                    public void onSubscribe(Disposable disposable) {

                    }

                    @Override
                    public void onNext(String s) {
                        Log.d(TAG, " onNext : s : " + s);
                    }

                    @Override
                    public void onError(Throwable throwable) {
                        Log.d(TAG, " onError : " + throwable.getMessage());
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG, " onComplete ");
                    }
                });
    }

打印结果

onNext : s : 1
onNext : s : 2
subscribe : random : 5
onNext : s : 1
onNext : s : 2
subscribe : random : 2
onNext : s : 3
onComplete 

日常在处理错误异常的时候,我们可能还需要配合do操作符的方法,在某些合适的节点进行处理。这个以后再说吧。


参考资料,参考但不局限以下链接
http://reactivex.io/documentation/operators.html#transforming

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值