異常處理
在Rxjava訂閱的Observable有時會拋出異常,在RxJava中有兩大類策略,一個是准備備用的Observable,在發生異常時將subscriber訂閱到新的Observable上,第二種是重試。
catch
第一種策略是捕獲異常並使用新的Observable來替換出現異常的Observable
方法有
onErrorReturn:返回單個對象
onErrorResumeNext:當拋出Throwable時返回一個新的Observable
onExceptionResumeNext:同onErrorResumeNext但只有拋出Exception時才會觸發
@Test
public void onException() {
Observable<Object> obs = Observable
.create(sub -> {
for (int i = 0; i < 10; i++) {
if (i == 1) {
//拋出異常
sub.onError(new RuntimeException("error"));
}
sub.onNext(i);
}
});
obs.onExceptionResumeNext(Observable.just("new resumed observable"))
.subscribe(obj -> System.out.println(obj));
}
-------輸出---------
0
new resumed observable
從輸出中看出當遇到異常后會調用注冊的備用Observable
Retry
該策略當遇到exception時會進行重試
有兩類方法
retry:可以根據重試次數和錯誤原因來判斷是否需要重試
@Test
public void retry() {
Observable<Object> obs = Observable
.create(sub -> {
for (int i = 0; i < 10; i++) {
if (i == 1) {
sub.onError(new RuntimeException("error"));
}
sub.onNext(i);
}
});
obs.retry((time,ex)->{
if(time==2 && ex instanceof RuntimeException){
return false;
}
return true;
})
.subscribe(obj -> System.out.println(obj));
}
-------輸出---------
0
0
rx.exceptions.OnErrorNotImplementedException: error
可以看到retry中判斷次數和錯誤類型根據返回決定是否要重試
retryWhen:通過將異常組成Observable並通過返回的Observable的結果來判斷是否重試
下面是官方的例子,第一次會1秒重試,第二次等待2秒,第三次等待3秒,第四次停止重試
@Test
public void retryWhen(){
Observable.create((s) -> {
s.onNext("subcribe");
s.onError(new RuntimeException("always fails"));
}).retryWhen(attempts -> {
return attempts.zipWith(Observable.range(1, 3), (n, i) -> i).flatMap(i -> {
System.out.println("delay retry by " + i + " second(s)");
return Observable.timer(i, TimeUnit.SECONDS);
});
}).toBlocking().forEach(System.out::println);
}
-------輸出---------
subcribe
delay retry by 1 second(s)
subcribe
delay retry by 2 second(s)
subcribe
delay retry by 3 second(s)
subcribe
