错误处理操作符

来源:互联网 发布:域名备案举报 编辑:程序博客网 时间:2024/04/30 11:28

错误处理操作符

错误处理操作符主要是在Observable的onError中拦截,做一些事情。

catch操作符

onErrorReturn

让Observable遇到错误时候发生一个特殊的数据并且正常终止,比如

 Observable.just(1, 2, 3, 4, 5).map(new Func1<Integer, String>() {            @Override            public String call(Integer integer) {                if (integer == 4) {                    throw new IllegalArgumentException("hahaha");                }                return integer + "str";            }        }).onErrorReturn(new Func1<Throwable, String>() {            @Override            public String call(Throwable throwable) {                Log.i(TAG, throwable.getMessage());                return "Bingo";            }        }).subscribe(new Action1<String>() {            @Override            public void call(String s) {                Log.i(TAG, "Result == " + s);            }        });

输出结果:

10-26 13:25:46.623 19493-19493/fortunetelling.mmc.oms.rxjavademo I/MainActivityLOG: Result == 1str10-26 13:25:46.623 19493-19493/fortunetelling.mmc.oms.rxjavademo I/MainActivityLOG: Result == 2str10-26 13:25:46.623 19493-19493/fortunetelling.mmc.oms.rxjavademo I/MainActivityLOG: Result == 3str10-26 13:25:46.623 19493-19493/fortunetelling.mmc.oms.rxjavademo I/MainActivityLOG: hahaha10-26 13:25:46.633 19493-19493/fortunetelling.mmc.oms.rxjavademo I/MainActivityLOG: Result == Bingo

说明:onErrorReturn操作符他会拦截错误,然后在拦截错误之后,不再继续发射源Observable的数据,同时,他将在Func1中返回一个对应的可被观测的数据传递到onNext中,然后调用了onComplete方法完成这一次的Observable过程。

onErrorResumeNext

让Observable遇到错误时开始发射第二个Observable数据序列,例子

 Observable<String> observable = Observable.just(1, 2, 3, 4, 5).map(new Func1<Integer, String>() {            @Override            public String call(Integer integer) {                if (integer == 4) {                    throw new IllegalArgumentException("hahaha");                }                return integer + "str";            }        });  observable.onErrorResumeNext(new Func1<Throwable, Observable<? extends String>>() {            @Override            public Observable<? extends String> call(Throwable throwable) {                return Observable.just("Bingo","Hello");            }        }).subscribe(new Action1<String>() {            @Override            public void call(String s) {                Log.i(TAG, "onErrorResumeNext == " + s);            }        });

结果:

10-26 13:40:56.843 5987-5987/fortunetelling.mmc.oms.rxjavademo I/MainActivityLOG: onErrorResumeNext == 1str10-26 13:40:56.843 5987-5987/fortunetelling.mmc.oms.rxjavademo I/MainActivityLOG: onErrorResumeNext == 2str10-26 13:40:56.843 5987-5987/fortunetelling.mmc.oms.rxjavademo I/MainActivityLOG: onErrorResumeNext == 3str10-26 13:40:56.843 5987-5987/fortunetelling.mmc.oms.rxjavademo I/MainActivityLOG: onErrorResumeNext == Bingo10-26 13:40:56.843 5987-5987/fortunetelling.mmc.oms.rxjavademo I/MainActivityLOG: onErrorResumeNext == Hello

可以看到他是终止了继续发射,但是他可以补充发射,就是在遇到错误的时候,可以在源Observable基础上面继续发射多个Observable直到结束。
他的重载函数:

Observable<T> onErrorResumeNext(final Observable<? extends T> resumeSequence)

使用也是类似,他也是可以在遇到错误之后发射多个Observable。

onExceptionResumeNext

让Observable遇到错误时发射继续发射后面的数据项,例子

 Observable<String> observable = Observable.just(1, 2, 3, 4, 5).map(new Func1<Integer, String>() {            @Override            public String call(Integer integer) {                if (integer == 4) {                    throw new Error("hahaha");                }                return integer + "str";            }        });  observable.onExceptionResumeNext(Observable.just("A", "B")).subscribe(new Observer<String>() {            @Override            public void onCompleted() {                Log.i(TAG, "onCompleted");            }            @Override            public void onError(Throwable e) {                Log.i(TAG, "onError"+e.getMessage());            }            @Override            public void onNext(String s) {                Log.i(TAG, "onNext"+s);            }        });

输出:

10-26 13:49:21.803 16041-16041/fortunetelling.mmc.oms.rxjavademo I/MainActivityLOG: onNext1str10-26 13:49:21.803 16041-16041/fortunetelling.mmc.oms.rxjavademo I/MainActivityLOG: onNext2str10-26 13:49:21.803 16041-16041/fortunetelling.mmc.oms.rxjavademo I/MainActivityLOG: onNext3str10-26 13:49:21.813 16041-16041/fortunetelling.mmc.oms.rxjavademo I/MainActivityLOG: onErrorhahaha

加入不是抛出Error,而是Exception的子类的时候,则结果是:

10-26 13:50:57.643 17881-17881/fortunetelling.mmc.oms.rxjavademo I/MainActivityLOG: onNext1str10-26 13:50:57.643 17881-17881/fortunetelling.mmc.oms.rxjavademo I/MainActivityLOG: onNext2str10-26 13:50:57.643 17881-17881/fortunetelling.mmc.oms.rxjavademo I/MainActivityLOG: onNext3str10-26 13:50:57.643 17881-17881/fortunetelling.mmc.oms.rxjavademo I/MainActivityLOG: onNextA10-26 13:50:57.643 17881-17881/fortunetelling.mmc.oms.rxjavademo I/MainActivityLOG: onNextB10-26 13:50:57.643 17881-17881/fortunetelling.mmc.oms.rxjavademo I/MainActivityLOG: onCompleted

说明onExceptionResumeNext操作符是在上级源Observable出现的是Exception的子类的时候调用他自己的Observable继续发射下去,同时是不回再去发射源Observable的数据。但是假如上级源Observable出现的不是Exception的子类的时候,那么他会直接调用onError方法结束发射。
对应的图:
onErrorReturn:

onErrorResumeNext:

onExceptionResumeNext:

retry操作符

retry操作符不会把错误传递到Observer的onError当中去。他可以不停的retry,尝试能够让源Observable正常发射结束。

retry 操作符

他会在源Observable在发生error的时候不断的重新去调用源数据,重头开始发射,存在了数据可能重复的结果,例如:

 Observable<String> observable = Observable.range(10, 3).map(new Func1<Integer, String>() {            @Override            public String call(Integer integer) {                if(integer == 11){                    throw new IllegalArgumentException("exception");                }                return integer.toString() + "retry";            }        });        observable.retry().subscribe(new Action1<String>() {            @Override            public void call(String s) {                Log.i(TAG, s);            }        });

结果是不断的打印

10retry

重载函数:

Observable<T> retry(final long count)

他可以设置重试次数,超出重试次数之后任然发生错误,那么他将会调用onError方法,例子:

 Observable<String> observable = Observable.range(10, 3).map(new Func1<Integer, String>() {            @Override            public String call(Integer integer) {                if(integer == 11){                    throw new IllegalArgumentException("exception");                }                return integer.toString() + "retry";            }        });        observable.retry(2).subscribe(new Action1<String>() {            @Override            public void call(String s) {                Log.i(TAG, s);            }        }, new Action1<Throwable>() {            @Override            public void call(Throwable throwable) {                Log.i(TAG, throwable.getMessage());            }        });

输出:

10-26 14:22:50.137 4099-4099/com.example.user.testproject I/RxJavaTest: 10retry10-26 14:22:50.138 4099-4099/com.example.user.testproject I/RxJavaTest: 10retry10-26 14:22:50.138 4099-4099/com.example.user.testproject I/RxJavaTest: 10retry10-26 14:22:50.138 4099-4099/com.example.user.testproject I/RxJavaTest: exception

重载函数

retry(Func2<Integer, Throwable, Boolean> predicate)

他可以设定某种界限,在不超出某个条件之下不断的重试,或者说只要是返回了true都会重试,反之停止,停止之后还是发生了错误,就会调用onError方法,例如

 Observable<String> observable = Observable.range(10, 3).map(new Func1<Integer, String>() {            @Override            public String call(Integer integer) {                if(integer == 11){                    throw new IllegalArgumentException("exception");                }                return integer.toString() + "retry";            }        });        observable.retry(new Func2<Integer, Throwable, Boolean>() {            @Override            public Boolean call(Integer integer, Throwable throwable) {                return integer<3;            }        }).subscribe(new Action1<String>() {            @Override            public void call(String s) {                Log.i(TAG, s);            }        }, new Action1<Throwable>() {            @Override            public void call(Throwable throwable) {                Log.i(TAG, throwable.getMessage());            }        });

他的意思是,在重试次数少于3的时候就会重试,否则就不会,输出:

10-26 14:28:34.882 8577-8577/com.example.user.testproject I/RxJavaTest: 10retry10-26 14:28:34.883 8577-8577/com.example.user.testproject I/RxJavaTest: 10retry10-26 14:28:34.883 8577-8577/com.example.user.testproject I/RxJavaTest: 10retry10-26 14:28:34.883 8577-8577/com.example.user.testproject I/RxJavaTest: exception

图:

retryWhen

Observable<String> observable = Observable.range(10, 3).map(new Func1<Integer, String>() {            @Override            public String call(Integer integer) {                if(integer == 11){                    throw new IllegalArgumentException("exception");                }                return integer.toString() + "retry";            }        });        observable.retryWhen(new Func1<Observable<? extends Throwable>, Observable<?>>() {            @Override            public Observable<?> call(Observable<? extends Throwable> observable) {               return observable.zipWith(Observable.range(1, 3), new Func2<Throwable, Integer, Object>() {                   @Override                   public Object call(Throwable throwable, Integer integer) {                       return "123";                   }               });            }        }).subscribe(new Action1<String>() {            @Override            public void call(String s) {                Log.i(TAG, s);            }        }, new Action1<Throwable>() {            @Override            public void call(Throwable throwable) {                Log.i(TAG, throwable.getMessage());            }        });

输出:

10-26 15:06:44.358 26227-26227/com.example.user.testproject I/RxJavaTest: 10retry10-26 15:06:44.359 26227-26227/com.example.user.testproject I/RxJavaTest: 10retry10-26 15:06:44.359 26227-26227/com.example.user.testproject I/RxJavaTest: 10retry

说明:这里使用了zipWith限制了retryWhen的次数,当超出了三次之后,zipWith回隐式的调用onComplete方法,所以这里的Observer的onError方法并不会被调用。

例子来源:【译】对RxJava中.repeatWhen()和.retryWhen()操作符的思考
关于:

Observable<T> retryWhen(final Func1<? super Observable<? extends Throwable>, ? extends Observable<?>> notificationHandler)

中的notificationHandler的Observable返回说明:

– 如果返回的 Observable 发射了一个数据,retryWhen 将会执行重试操作– 如果返回的 Observable 发射了一个错误信息,retryWhen 将会发射一个错误并不会重试– 如果返回的 Observable 正常结束了,retryWhen 也正常结束。

出处:RxJava 教程第三部分:驯服数据流之 高级错误处理
也就是说,其实retryWhen的Func1返回的Observable的值并不重要,是他的类型重要,他只是判断是否可以继续执行retryWhen,例如:

Observable<Integer> source = Observable.create(o -> {    o.onNext(1);    o.onNext(2);    o.onError(new Exception("Failed"));});source.retryWhen((o) -> o        .take(2)        .delay(100, TimeUnit.MILLISECONDS))    .timeInterval()    .subscribe(        System.out::println,        System.out::println);

结果:

TimeInterval [intervalInMilliseconds=21, value=1]TimeInterval [intervalInMilliseconds=0, value=2]TimeInterval [intervalInMilliseconds=104, value=1]TimeInterval [intervalInMilliseconds=0, value=2]TimeInterval [intervalInMilliseconds=103, value=1]TimeInterval [intervalInMilliseconds=0, value=2]

出处:RxJava 教程第三部分:驯服数据流之 高级错误处理
图:

他还有一个重载的操作符可以指定调度器Scheduler

Observable<T> retryWhen(final Func1<? super Observable<? extends Throwable>, ? extends Observable<?>> notificationHandler, Scheduler scheduler)
0 0
原创粉丝点击