zip操作符的error處理

熟悉rxjava的同學肯定對操作符不會陌生,比如我們使用map操作符處理數據,使用zip操作符合並多個請求,這裏演示下zip操作符的對error情況的處理。

比如說我們同時請求了兩個接口,在兩個接口都響應的情況下才會展示數據,這裏我們使用zip操作符來實現。

zip操作符合並請求

我們先模擬兩個請求的響應:responseOneObservable和responseTwoObservable,這裏responseTwoObservable我們模擬了錯誤的場景——onError.

Observable<ZipOneBean> responseOneObservable = Observable.create(new ObservableOnSubscribe<ZipOneBean>() {
    @Override
    public void subscribe(ObservableEmitter<ZipOneBean> emitter) {
        ZipOneBean zipOneBean = new ZipOneBean();
        zipOneBean.setName("zipOneBean");
        emitter.onNext(zipOneBean);
        emitter.onComplete();
    }
})
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread());

Observable<ZipTwoBean> responseTwoObservable = Observable.create(new ObservableOnSubscribe<ZipTwoBean>() {
    @Override
    public void subscribe(ObservableEmitter<ZipTwoBean> emitter) {
        ZipTwoBean zipTwoBean = new ZipTwoBean();
        zipTwoBean.setName("zipTwoBean");
        emitter.onError(new RuntimeException("阿西吧"));
    }
})
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread());

接着使用zip操作符進行合併:

Observable.zip(responseOneObservable, responseTwoObservable, new BiFunction<ZipOneBean, ZipTwoBean, ArrayList<ZipBaseData>>() {
    @Override
    public ArrayList<ZipBaseData> apply(ZipOneBean zipOneBean, ZipTwoBean zipTwoBean) {
        ArrayList<ZipBaseData> testDataList = new ArrayList();
        // Add test data from response responseOne & responseTwo
        testDataList.add(zipOneBean);
        testDataList.add(zipTwoBean);
        return testDataList;
    }
}).subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Observer<ArrayList<ZipBaseData>>() {
            @Override
            public void onSubscribe(Disposable d) {
                Log.e(TAG, "onSubscribe");
            }

            @Override
            public void onNext(ArrayList<ZipBaseData> zipBaseData) {
                Log.e(TAG, "onNext zipBaseData:" + zipBaseData);
            }

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

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

運行代碼,輸出結果如下:最終走的是onError方法,

E/ZipErrorHandle: onSubscribe
E/ZipErrorHandle: onError e:阿西吧

onErrorReturn

這種做法肯定不能滿足需求,如果兩個接口中的一個掛了,導致另外一個正常接口的數據也不展示,這個明顯不合邏輯。所以我們需要在請求響應錯誤的時候做下處理,返回默認數據或者特定的數據,標識這個請求失敗,不影響別的接口的數據展示。代碼如下:

Observable<ZipOneBean> responseOneObservable = Observable.create(new ObservableOnSubscribe<ZipOneBean>() {
    @Override
    public void subscribe(ObservableEmitter<ZipOneBean> emitter) {
        ZipOneBean zipOneBean = new ZipOneBean();
        zipOneBean.setName("zipOneBean");
        emitter.onNext(zipOneBean);
        emitter.onComplete();
    }
}).onErrorReturn(new Function<Throwable, ZipOneBean>() {
    @Override
    public ZipOneBean apply(Throwable throwable) {
        ZipOneBean zipOneBean = new ZipOneBean();
        zipOneBean.setName("大哥我錯了,我是zipOneBean");
        return zipOneBean;
    }
})
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread());

Observable<ZipTwoBean> responseTwoObservable = Observable.create(new ObservableOnSubscribe<ZipTwoBean>() {
    @Override
    public void subscribe(ObservableEmitter<ZipTwoBean> emitter) {
        ZipTwoBean zipTwoBean = new ZipTwoBean();
        zipTwoBean.setName("zipTwoBean");
        emitter.onError(new RuntimeException("阿西吧"));
    }
}).onErrorReturn(new Function<Throwable, ZipTwoBean>() {
    @Override
    public ZipTwoBean apply(Throwable throwable) {
        ZipTwoBean zipTwoBean = new ZipTwoBean();
        zipTwoBean.setName("大哥我錯了,我是zipTwoBean");
        return zipTwoBean;
    }
})
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread());

接下來我們再運行代碼,輸出如下:

E/ZipErrorHandle: onSubscribe
E/ZipErrorHandle: onNext zipBaseData:[ZipBaseData{name='zipOneBean'}, ZipBaseData{name='大哥我錯了,我是zipTwoBean'}]
E/ZipErrorHandle: onComplete

可以看出即使一個請求出錯,也是走了成功的回調的。

參考

https://stackoverflow.com/questions/41342844/rxjava-how-to-handle-error-with-zip-operator

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章