RxJava系列之常用異常操作符

系列文章

RxJava系列之簡介和觀察者設計模式
RxJava系列之上游與下游
RxJava系列之常用創建型操作符
RxJava系列之常用變換操作符
RxJava系列之常用過濾操作符
RxJava系列之常用條件操作符
RxJava系列之常用合併操作符
RxJava系列之常用異常操作符
RxJava系列之線程切換實戰
RxJava系列之背壓模式
RxJava系列之配合Retrofit
RxJava系列之泛型高級
RxJava系列之手寫create操作符
RxJava系列之手寫create操作符增加泛型限定
RxJava系列之手寫just操作符
RxJava系列之手寫map操作符
RxJava系列之手寫切換線程

異常操作符

異常操作符可以攔截到上游的onError事件,從而修改發射到下游的事件。主要分爲兩大類,可以攔截throws new Exception()的和不能攔截throws new Exception的。

onErrorReturn

1.能夠接收e.onError, 2.如果接收到異常,會中斷上游後續發射的所有事件


    /**
     * onErrorReturn異常操作符:1.能夠接收e.onError,  2.如果接收到異常,會中斷上游後續發射的所有事件
     * error
     * @param view
     */
    public void r01(View view) {

        // 上游 被觀察者
        Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                for (int i = 0; i < 100; i++) {
                    if (i == 5) {
                        // RxJava中是不標準的
                        // throw new IllegalAccessError("我要報錯了");

                        // RxJava標準的
                        e.onError(new IllegalAccessError("我要報錯了")); // 發射異常事件
                    }
                    e.onNext(i);
                }
                e.onComplete();
            }
        })

        // 在上游 和 下游之間 添加異常操作符
        .onErrorReturn(new Function<Throwable, Integer>() {
            @Override
            public Integer apply(Throwable throwable) throws Exception {
                // 處理,紀錄,異常,通知給下一層
                Log.d(TAG, "onErrorReturn: " + throwable.getMessage());
                return 400; // 400代表有錯誤,給下一層,目前 下游 觀察者
            }
        })

        .subscribe(new Observer<Integer>() { // 完整版 下游 觀察者
            @Override
            public void onSubscribe(Disposable d) {

            }

            // 如果使用了 異常操作符 onNext: 400
            @Override
            public void onNext(Integer integer) {
                Log.d(TAG, "onNext: " + integer); // 400
            }

            // 如果不使用 異常操作符 onError
            @Override
            public void onError(Throwable e) {
                Log.d(TAG, "onError: " + e.getMessage());
            }

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

    }

onErrorResumeNext

onErrorResumeNext 異常操作符:1.能夠接收e.onError,
onErrorReturn可以返回標識400 VS onErrorResumeNext可以返回被觀察者(被觀察者可以再次發射多次事件給 下游)

  // onErrorResumeNext 異常操作符:1.能夠接收e.onError,
    // onErrorReturn可以返回標識400    對比   onErrorResumeNext可以返回被觀察者(被觀察者可以再次發射多次事件給 下游)
    // error
    public void r02(View view) {

        // 上游
        Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                for (int i = 0; i < 100; i++) {
                    if (i == 5) {
                        e.onError(new Error("錯錯錯"));
                    } else {
                        e.onNext(i);
                    }
                }
                e.onComplete();
            }
        })

        .onErrorResumeNext(new Function<Throwable, ObservableSource<? extends Integer>>() {
            @Override
            public ObservableSource<? extends Integer> apply(Throwable throwable) throws Exception {

                // onErrorResumeNext 返回的是 被觀察者,所以再多次發射給 下游 給 觀察者接收
                return Observable.create(new ObservableOnSubscribe<Integer>() {
                    @Override
                    public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                        e.onNext(400);
                        e.onNext(400);
                        e.onNext(400);
                        e.onNext(400);
                        e.onNext(400);
                        e.onNext(400);
                        e.onComplete();
                    }
                });
            }
        })

        .subscribe(new Observer<Integer>() { // 下游
            @Override
            public void onSubscribe(Disposable d) {

            }

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

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

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

    }

onExceptionResumeNext

onExceptionResumeNext 操作符,能在發生異常的時候,扭轉乾坤,可以攔截到throws new Exception。

 /**
     * exception
     * onExceptionResumeNext 操作符,能在發生異常的時候,扭轉乾坤,(這種錯誤一定是可以接受的,才這樣使用)
     * 慎用:自己去考慮,是否該使用
     * @param view
     */
    public void r03(View view) {

        // 上游
        Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                for (int i = 0; i < 100; i++) {
                    if (i == 5) {
                       /* throw new 其他Exception("錯了");
                        throw new IllegalAccessException("錯了");*/
                        throw new Exception("錯了");
                        // e.onError(new IllegalAccessException("錯了")); // 異常事件
                    } else {
                        e.onNext(i);
                    }

                }
                e.onComplete(); // 一定要最後執行

                /**
                 * e.onComplete();
                 * e.onError
                 * 會報錯
                 */
            }
        })

        // 在上游和下游中間 增加 異常操作符
        .onExceptionResumeNext(new ObservableSource<Integer>() {
            @Override
            public void subscribe(Observer<? super Integer> observer) {
                observer.onNext(404); // 可以讓程序 不崩潰的
            }
        })

        // 下游
        .subscribe(new Observer<Integer>() {
            @Override
            public void onSubscribe(Disposable d) {

            }

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

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

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

retry

retry 重試操作符也屬於異常操作符,因爲可以攔截到異常。攔截到異常可以重試,重試次數可以設置,重試次數也可以獲取到。

 /**
     * retry 重試操作符 異常處理操作符中
     * @param view
     */
    public void r04(View view) {

        // 上游
        Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                for (int i = 0; i < 100; i++) {
                    if (i == 5) {
                       /* throw new 其他Exception("錯了");
                        throw new IllegalAccessException("錯了");*/
                        // throw new Exception("錯了");

                        // rxJava標準的
                        e.onError(new IllegalAccessException("錯了")); // 異常事件
                    } else {
                        e.onNext(i);
                    }
                }
                e.onComplete(); // 一定要最後執行
            }
        })

        // todo 演示一
        /*.retry(new Predicate<Throwable>() {
            @Override
            public boolean test(Throwable throwable) throws Exception {
                Log.d(TAG, "retry: " + throwable.getMessage());
                // return false; // 代表不去重試
                return true; // 一直重試,不停的重試
            }
        })*/

        // todo 演示二 重試次數
        /*.retry(3, new Predicate<Throwable>() {
            @Override
            public boolean test(Throwable throwable) throws Exception {
                Log.d(TAG, "retry: " + throwable.getMessage());
                return true;
            }
        })*/

        // todo 演示三 打印重試了多少次,計數     Throwable  +  count
        .retry(new BiPredicate<Integer, Throwable>() {
            @Override
            public boolean test(Integer integer, Throwable throwable) throws Exception {
                Thread.sleep(2);
                Log.d(TAG, "retry: 已經重試了:" + integer + "次  e:" + throwable.getMessage());
                return true; // 重試
            }
        })

        .subscribe(new Observer<Integer>() {
            @Override
            public void onSubscribe(Disposable d) {

            }

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

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

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

    }

總結

1.RxJava中是不標準的throw new IllegalAccessError(“我要報錯了”);
2. RxJava標準的e.onError(XXX);
3.onErrorReturn最先攔截到e.onError並且可以給下游返回一個 標識400, throw new XXX 攔截不到,整個程序奔潰
4.onErrorResumeNext最先攔截到e.onError並且可以給下游返回一個 被觀察者(還可以再次發送), throw new XXX 攔截不到,整個程序奔潰
5.onExceptionResumeNext 能在發生異常的時候,扭轉乾坤,能夠處理 throw new XXX,可以真正的讓App不奔潰
6.retry return false; 代表不去重試 return true; 不停的重試, 演示二 重試次數, 演示三 打印重試了多少次,計數

發佈了91 篇原創文章 · 獲贊 1 · 訪問量 5547
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章