Rx中, 很容易處理異常, 整個鏈式調用過程中,如果異常不做處理, 最后都會交給onError
;
不要過渡的依賴onError
; onError
應該是在數據實在是無法處理的情況下,才被調用; 因為onError
一旦被調用, 即意味著整個事件流結束;
在傳統的Java中, 一般產生異常, 可以自己決定處理或者拋出, 在Rx中也類似, 可以自己決定在產生異常后, 如何處理;
Catch
和傳統Java中Catch類似, 獲取異常,然后自行決定如何處理;
onErrorReturn
onErrorReturn
操作符作用: 當發生錯誤是, 發送一個默認值,然后結束數據流(即調用onComplete
); 使用后,Subscribe的onError
方法不會被調用,會正常的調用onComplete
結束;
onErrorResumeNext
onErrorResumeNext
操作符的作用: 當錯誤發生時, 用一個數據流代替當前數據流, 繼續發送數據; 和上面一樣,Subscribe的onError方法不會被調用
onExceptionResumeNext
onExceptionResumeNext
類似, 唯一的區別就是onExceptionResumeNext
捕獲的是異常
如果拋出的Throwable不是一個Exception, 該操作符無法捕獲
Retry
如果發生了異常, 也可以使用retry
重新訂閱; 使用retry
重新訂閱數據流后, Observable會從頭重新發射數據, 意味著可能會重復處理數據
retry有三個重載方法
- retry 無限重新訂閱
- retry(long) 帶有最大重試次數, 次數超過,則不再重試
- retry(Func) 帶有一個判讀函數, 如果返回true, 則重試; 返回false,則結束
retryWhen
retryWhen
和retry
類似, 不過接受一個函數, 該函數返回一個Observable, 由Observable發射的數據, 決定是否需要重新訂閱
- 如果返回的Observable發射一個數據, 則重新訂閱
- 如果返回的Observable發射一個錯誤, 則不會重試
返回的Observable發射的數據類型不重要; Observable只是用來判斷是否需要重試
不結束當前數據流, 捕獲(處理,忽略)異常
在平常編碼中, 處理一序列的數據, 通常對其中的一個數據處理異常時, 我們通常會捕獲忽略異常, 跳過該數據, 繼續處理剩下的數據;
上述的操作符中, 上面的操作符并不能實現該功能; onErrorReturn
遇到異常時,會結束該數據留, 不會處理剩下的數據; 而retry
會從頭重新發射數據, 有重復數據;
這種情況需要和flatMap
一起搭配使用; flatMap
可以把每項數據轉換成為一個Observable, 然后就可以針對每個數據處理異常了
Random random = new Random();
Observable<Integer> observable =
Observable.create(o -> {
o.onNext(random.nextInt());
o.onNext(random.nextInt());
o.onError(new Exception());
o.onNext(random.nextInt());
}).flatMap(o -> Observable.just(o)
.map(Object::toString)
.map(Integer::valueOf)
.onErrorReturn(throwable -> -1)
);