RxJava 操作符之事件回調 do 系列操作符

繼續之前的RxJava 操作符系列文檔,今天來研究一下do 操作符,也可以理解爲 rxJava 各種事件的回調,比如當發生了onError ,我想在此做些什麼,就可以使用一個回調操作,就可以用doOnError () 來實現。好了,老規矩,先列出參考文章

http://reactivex.io/documentation/operators/do.html

來看看官方解釋

register an action to take upon a variety of Observable lifecycle events

意思就是註冊一個動作來監聽生命週期的各個事件。想想有什麼事件呢? 訂閱,取消訂閱,onNext, onError, onComplete, 終止,結束等等,官方列舉有如下事件:

 

代碼展示

 Observable<String> mStringObservable;

    Observable<String> mStringErorObservable;

    Observer<String> mStringSubscriber;


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_do_operation);

        mStringErorObservable = Observable.create(new ObservableOnSubscribe<String>() {

            @Override
            public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                for (int i = 0; i < 5; i++) {
                    if(i == 3) {
                        emitter.onError(new Throwable("ERROR"));
                    }else{
                        emitter.onNext(i + "");
                    }
                }
                emitter.onComplete();
            }
        });

        mStringObservable = Observable.create(new ObservableOnSubscribe<String>() {

            @Override
            public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                for (int i = 0; i < 5; i++) {
                    emitter.onNext(i + "");
                }
                emitter.onComplete();
            }
        });

        mStringSubscriber = new Observer<String>() {
            @Override
            public void onSubscribe(Disposable d) {
                Log.d(TAG, "onSubscribe: ");
            }

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

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

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

doError 、doOnNext 、 doComplete

public void doOnError(View view){
        mStringErorObservable.doOnError(new Consumer<Throwable>() {
            @Override
            public void accept(Throwable throwable) throws Exception {
                Log.d(TAG, "doOnError accept: " + throwable.getMessage());
            }
        }).subscribe(mStringSubscriber);
    }

日誌打印:

 D/DoOperateActivity: onSubscribe: 
 D/DoOperateActivity: onNext: 0
 D/DoOperateActivity: onNext: 1
 D/DoOperateActivity: onNext: 2
 D/DoOperateActivity: doOnError accept: ERROR
 D/DoOperateActivity: onError: ERROR

 結果分析:

由於註冊了DoOnError 函數,當遇到錯誤時,會先觸發 doOnError 回調,在執行onError 函數;類似的,onNext , onComplete對應的回調函數都會先於其本身執行。另外的,遇到錯誤onError後,onComplete 不會被執行,相當於異常終止,如果想要執行onComplete, 可以參考Error Handling 裏面的操作符。

public void doOnCompleteOnNextdoOnError(View view){
        mStringObservable.doOnError(new Consumer<Throwable>() {
            @Override
            public void accept(Throwable throwable) throws Exception {
                Log.d(TAG, "accept: " + throwable.getMessage());
            }
        }).doOnNext(new Consumer<String>() {
            @Override
            public void accept(String s) throws Exception {
                Log.d(TAG, "accept: " + s);
            }
        }).doOnComplete(new Action() {
            @Override
            public void run() throws Exception {
                Log.d(TAG, "run: doOnComplete");
            }
        }).subscribe(mStringSubscriber);
    }

日誌打印:

D/DoOperateActivity: onSubscribe: 
D/DoOperateActivity: accept: 0
D/DoOperateActivity: onNext: 0
D/DoOperateActivity: accept: 1
D/DoOperateActivity: onNext: 1
D/DoOperateActivity: accept: 2
D/DoOperateActivity: onNext: 2
D/DoOperateActivity: accept: 3
D/DoOperateActivity: onNext: 3
D/DoOperateActivity: accept: 4
D/DoOperateActivity: onNext: 4
D/DoOperateActivity: run: doOnComplete
D/DoOperateActivity: onComplete: 

結果分析:

這次用了一個正常的數據源,doOnNext 會在 onNext前調用,同理 doOnComplete 也是的。和第一個分析一致。注意:想要回調執行doOnComplete , 數據源必須調用onComplete , 否則觀察者不會執行onComplete, 而doOnComplete 的回調基於onComplete的,所以這樣說大家應該明白了。

doOnEach

The doOnEach operator allows you to establish a callback that the resulting Observable will call each time it emits an item. You can pass this callback either in the form of an Action that takes an onNext variety of Notification as its sole parameter, or you can pass in an Observer whose onNext method will be called as if it had subscribed to the Observable.

doOnEach運算符允許您建立一個回調,結果Observable每次發出一個項目時都會調用它。 您可以以Action的形式傳遞此回調,該Action將onNext各種Notification作爲其唯一參數,或者您可以傳入一個Observer,其onNext方法將被調用,就好像它已訂閱了Observable一樣。

就是會對觀察者的onNext onError onComplete 三個方法做出回調

我們可以看代碼:

 public void doEach(View view){
        mStringObservable.doOnEach(new Consumer<Notification<String>>() {
            @Override
            public void accept(Notification<String> stringNotification) throws Exception {
                Log.d(TAG, "accept: ");
            }
        }).subscribe(mStringSubscriber);

        mStringObservable.doOnEach(new Observer<String>() {
            @Override
            public void onSubscribe(Disposable d) {
                Log.d(TAG, "doOnEach onSubscribe: ");
            }

            @Override
            public void onNext(String s) {
                Log.d(TAG, " doOnEach onNext: " + s);
            }

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

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

日誌打印:

D/DoOperateActivity: onSubscribe: 
D/DoOperateActivity: accept: 
D/DoOperateActivity: onNext: 0
D/DoOperateActivity: accept: 
D/DoOperateActivity: onNext: 1
D/DoOperateActivity: accept: 
D/DoOperateActivity: onNext: 2
D/DoOperateActivity: accept: 
D/DoOperateActivity: onNext: 3
D/DoOperateActivity: accept: 
D/DoOperateActivity: onNext: 4
D/DoOperateActivity: accept: 
D/DoOperateActivity: onComplete: 
D/DoOperateActivity: onSubscribe: 
D/DoOperateActivity:  doOnEach onNext: 0
D/DoOperateActivity: onNext: 0
D/DoOperateActivity:  doOnEach onNext: 1
D/DoOperateActivity: onNext: 1
D/DoOperateActivity:  doOnEach onNext: 2
D/DoOperateActivity: onNext: 2
D/DoOperateActivity:  doOnEach onNext: 3
D/DoOperateActivity: onNext: 3
D/DoOperateActivity:  doOnEach onNext: 4
D/DoOperateActivity: onNext: 4
D/DoOperateActivity: doOnEach onComplete:
D/DoOperateActivity: onComplete: 

結果分析:

對onNext ,onComplete 都做出了響應,有點組合doOnNext 和 doOnComplete的意思。

然後我把數據源換成了mStringErrorObservale 後,日誌打印變成了

D/DoOperateActivity: onSubscribe: 
D/DoOperateActivity:  doOnEach onNext: 0
D/DoOperateActivity: onNext: 0
D/DoOperateActivity:  doOnEach onNext: 1
D/DoOperateActivity: onNext: 1
D/DoOperateActivity:  doOnEach onNext: 2
D/DoOperateActivity: onNext: 2
D/DoOperateActivity: doOnEach onError: java.lang.Throwable: ERROR
D/DoOperateActivity: onError: ERROR

其他的Do操作符

public void doOther(View view){
        mStringErorObservable.doOnTerminate(new Action() {
            @Override
            public void run() throws Exception {
                Log.d(TAG, "doOnTerminate run: ");
            }
        }).doOnSubscribe(new Consumer<Disposable>() {
            @Override
            public void accept(Disposable disposable) throws Exception {
                Log.d(TAG, "doOnSubscribe accept: ");
            }
        }).doOnLifecycle(new Consumer<Disposable>() {
            @Override
            public void accept(Disposable disposable) throws Exception {
                Log.d(TAG, "doOnLifecycle accept: ");
            }
        }, new Action() {
            @Override
            public void run() throws Exception {
                Log.d(TAG, "doOnLifecycle run: ");
            }
        }).doFinally(new Action() {
            @Override
            public void run() throws Exception {
                Log.d(TAG, "run: doFinally");
            }
        }).doAfterTerminate(new Action() {
            @Override
            public void run() throws Exception {
                Log.d(TAG, "run: doAfterTerminate");
            }
        }).subscribe(mStringSubscriber);
    }

日誌打印:

 D/DoOperateActivity: doOnSubscribe accept: 
 D/DoOperateActivity: doOnLifecycle accept: 
 D/DoOperateActivity: onSubscribe: 
 D/DoOperateActivity: onNext: 0
 D/DoOperateActivity: onNext: 1
 D/DoOperateActivity: onNext: 2
 D/DoOperateActivity: doOnTerminate run: 
 D/DoOperateActivity: onError: ERROR
 D/DoOperateActivity: run: doAfterTerminate
 D/DoOperateActivity: run: doFinally

其他的操作符,我們都能見名曉意,不用一一解釋了。

好了,do相關的操作符介紹完了,歸納就是一句話:對各種事件監聽並做出迴應。

register an action to take upon a variety of Observable lifecycle events

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