Rxjava異常處理


異常處理

在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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM