RxJava系列之上游與下游

系列文章

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

什麼是上游和下游

在RxJava中,我們將事件的起源稱之爲上游,事件的處理稱之爲下游。上游產生事件之後,發射給下游,下游接收到並請求。如下圖所示:

在這裏插入圖片描述

簡單例子

/**
     * 流程整理 1
     * @param vieww
     */
    public void r04(View vieww) {

        // 上游 Observable 被觀察者
        Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                // 發射
                Log.d(TAG, "上游 subscribe: 開始發射..."); // todo 2
                emitter.onNext("RxJavaStudy");

                emitter.onComplete(); // 發射完成  // todo 4

                // 上游的最後log纔會打印
                Log.d(TAG, "上游 subscribe: 發射完成");
            }
        }).subscribe(
         // 下游 Observer 觀察者
         new Observer<String>() {
            @Override
            public void onSubscribe(Disposable d) {
                // 彈出 加載框 ....
                Log.d(TAG, "上游和下游訂閱成功 onSubscribe 1"); // todo 1
            }

            @Override
            public void onNext(String s) {
                Log.d(TAG, "下游接收 onNext: " + s); // todo 3
            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onComplete() {
                // 隱藏加載框
                Log.d(TAG, "下游接收完成 onComplete"); // todo 5  只有接收完成之後,上游的最後log纔會打印
            }
        });

        /**
         *  D/MainActivity: 上游和下游訂閱成功 onSubscribe 1
         *  D/MainActivity: 上游 subscribe: 開始發射...
         *  D/MainActivity: 下游接收 onNext: RxJavaStudy
         *  D/MainActivity: 下游接收完成 onComplete
         *  D/MainActivity: 上游 subscribe: 發射完成
         */
    }

整個流程是,上下游訂閱成功,下游收到通知,處理訂閱成功事件。上游在訂閱成功的回調中發射事件,下游收到onNext回調,處理上游發送的事件。上游發送完成事件,下游收到onComplete回調。

另外一個例子

  /**
     * 流程整理2
     * @param vieww
     */
    public void r05(View vieww) {

        // 上游 Observable 被觀察者
        Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                // 發射
                Log.d(TAG, "上游 subscribe: 開始發射..."); // todo 2
                emitter.onNext("RxJavaStudy");

                // emitter.onComplete(); // 發射完成  // todo 4

                // 上游的最後log纔會打印
                // Log.d(TAG, "上游 subscribe: 發射完成");

                // emitter.onError(new IllegalAccessException("error rxJava"));

                // TODO 結論:在 onComplete();/onError 發射完成 之後 再發射事件  下游不再接收上游的事件
                /*emitter.onNext("a");
                emitter.onNext("b");
                emitter.onNext("c");*/
                // 發一百個事件

                emitter.onError(new IllegalAccessException("error rxJava")); // 發射錯誤事件
                emitter.onComplete(); // 發射完成
                // TODO 結論:已經發射了onComplete();, 再發射onError RxJava會報錯,不允許
                // TODO 結論:先發射onError,再onComplete();,不會報錯, 有問題(onComplete不會接收到了)
            }
        }).subscribe(
                // 下游 Observer 觀察者
                new Observer<String>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        // 彈出 加載框 ....
                        Log.d(TAG, "上游和下游訂閱成功 onSubscribe 1"); // todo 1
                    }

                    @Override
                    public void onNext(String s) {
                        Log.d(TAG, "下游接收 onNext: " + s); // todo 3
                    }

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

                    @Override
                    public void onComplete() {
                        // 隱藏加載框
                        Log.d(TAG, "下游接收完成 onComplete"); // todo 5  只有接收完成之後,上游的最後log纔會打印
                    }
                });

    }

在 onComplete();/onError 發射完成 之後 再發射事件 下游不再接收上游的事件
已經發射了onComplete();, 再發射onError RxJava會報錯,不允許
已經發射了onComplete();, 再發射onError RxJava會報錯,不允許

中斷事件

Disposable d;

    /**
     * 切斷下游,讓下游不再接收上游的事件,也就是說不會去更新UI
     * @param view
     */
    public void r06(View view) {
        // TODO 上游 Observable
        Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                for (int i = 0; i < 100; i++) {
                    e.onNext(i);
                }
                e.onComplete();
            }
        })

        // 訂閱下游
        .subscribe(new Observer<Integer>() {
            @Override
            public void onSubscribe(Disposable d) {
                MainActivity.this.d = d;
            }

            @Override
            public void onNext(Integer integer) {
                Log.d(TAG, "下游接收 onNext: " + integer);

                // 接收上游的一個事件之後,就切斷下游,讓下游不再接收
                // d.dispose();
            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onComplete() {

            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 切斷下游
        if (d != null) d.dispose();
    }

下游在訂閱成功之後onSubscribe(Disposable d) 回調方法傳遞過來Disposable對象,可以通過這個對象可以切斷下游。

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