天天看點

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, 終止,結束等等,官方列舉有如下事件:

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

代碼展示

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