Rxjava 過程分析一(簡單流程)

Rxjava 過程分析一

說明

  • 該文章是基於 Rxjava2 源碼。
  • 該篇只是講述 Rxjava 建議的用法,不涉及操作符和線程切換, 後兩個會有新的篇幅去寫。 一步一步的來。
  • 在源碼中那些判空還有 Rxjava 中 RxJavaPlugins 鉤子等在分析中去除(只關注用法和思想, 和主流程不管的暫時剔除)。
  • 由於習慣, 和 Rxjava2 中的命名。 我稱 emitter 爲上游, 也就是發射水(數據)的源頭, 結果回調給外部的 FlowableSubscriber, 我稱它爲下游。 上游流水流到下游!

最簡單的使用

Flowable.create(new FlowableOnSubscribe<String>() {
    @Override
    public void subscribe(FlowableEmitter<String> emitter) throws Exception {
         // emitter.onNext("");
        // emitter.onError();
       // emitter.onComplete();
    }
}, BackpressureStrategy.LATEST).subscribe(new FlowableSubscriber<String>() {
    @Override
    public void onSubscribe(Subscription s) {
    }
    @Override
    public void onNext(String s) {
    }
    @Override
    public void onError(Throwable t) {
    }
    @Override
    public void onComplete() {
    }
});

引發的思考

  1. 調用 emitter 的 onNext、 onError、 onComplete, 就會回調 FlowableSubscriber 中對應的方法。 那麼這兩個對象是一個嗎? 有什麼聯繫呢?
  2. 我們把上述代碼寫好後, 會自動調用並回調, 那麼上游發射器 emitter 是什麼時候觸發的呢? 該方法是什麼時機和誰調用的呢?

源碼分析

從創建開始

 public static <T> Flowable<T> create(FlowableOnSubscribe<T> source, BackpressureStrategy mode) {
    return new FlowableCreate<T>(source, mode);
}

簡單嗎大兄弟, 僅僅是創建了一個 FlowableCreate 類而已。 並對成員變量賦值。

簡單說說下游

在開發中, 可能很多都有在用回調吧。 再次機會我也想說說回調是咋回事。 其實 java 中的常用的內部類回調, 還是 c 的函數指針, 或者其語言的閉包(swift), 其實不要把它們想的多麼神奇。 就這麼想, 我把一個實例地址或者函數地址給你了, 你在內部去調用我的方法, 自然就運行到了外面了。

訂閱

 public final void subscribe(FlowableSubscriber<? super T> s) {
    try {
        Subscriber<? super T> z = s;
        subscribeActual(z);
    } catch (NullPointerException e) { 
        throw e;
    } catch (Throwable e) {

    }
}

信息量很少, 只是調用了當前 Flowable 的 subscribeActual() 方法。 我們前面知道當前的 Flowable 是 FlowableCreate 對象, 所以進 FlowableCreate 中去看看做了什麼事情。

 public void subscribeActual(Subscriber<? super T> t) {
    BaseEmitter<T> emitter;

    switch (backpressure) {
    case MISSING: {
        emitter = new MissingEmitter<T>(t);
        break;
    }
    case ERROR: {
        emitter = new ErrorAsyncEmitter<T>(t);
        break;
    }
    case DROP: {
        emitter = new DropAsyncEmitter<T>(t);
        break;
    }
    case LATEST: {
        emitter = new LatestAsyncEmitter<T>(t);
        break;
    }
    default: {
        emitter = new BufferAsyncEmitter<T>(t, bufferSize());
        break;
    }
    }

    t.onSubscribe(emitter);
    try {
        source.subscribe(emitter);
    } catch (Throwable ex) {
        Exceptions.throwIfFatal(ex);
        emitter.onError(ex);
    }
}

我們這裏不去討論背壓等問題, 所以我們只是關注主要流程和關鍵方法。 其中一眼就可以看到關鍵的一個就是在 try 塊中的 source.subscribe(emitter); source 是什麼呀? 就是我們在 new FlowableCreate 傳進來的 Flowable.create(new FlowableOnSubscribe()) 中 FlowableOnSubscribe 對象。 source 的 subscribe 這不就是運行了 外部 FlowableOnSubscribe 的 subscribe嘛, 所以外部調用 onNext, onError, onComplete 方法, 其實調用了 內部 emitter 中對應的方法。 我們以背壓爲 LATEST 爲例看看 LatestAsyncEmitter 被調用的方法做了什麼事情。 先多說一句, 初始化 emitter 時我們傳入的是下游哦, 下游相應的方法調用了, 那麼外部的就會看似回調出去拿到結果了!

我們以 onNext 爲例, 看看 LatestAsyncEmitter 被調用到 onNext 做了什麼事情。

 public void onNext(T t) {
    queue.set(t);
    drain();
}

看到是先把結果存到了隊列中, 我們不考慮背壓, 所以我們看主要的大致流程哈。 顯然下一個有用的代碼就是 drain() 了。

 void drain() {
    final Subscriber<? super T> a = downstream;
    final AtomicReference<T> q = queue;
		// ......
		T o = q.getAndSet(null);
		// ......
    	a.onNext(o);
		// ......
}

其中 downstream 就是我們外部的 FlowableSubscriber 及下游了。 我們可以看到, 簡單的從隊列中取出數據, 直接調用了下游的 onNext。 就這樣數據就被從上游流向了下游。

前面的疑惑問題

  • 上游和下游是一個東西嗎? 它們的關係是什麼?

這個問題從上面的分析已經很明顯了。 上游和下游不是一個東西, 上游 emitter 調用相應的方法去回調下游的方法。

  • 在哪一個時刻觸發的事件流動呢?

其實是在上游 emitter 調用相應的方法那一刻, 比如調用 onNext。 那麼是在哪一個時機觸發調用的呢? 很明顯是在訂閱時, 調用了 subscribeActual 中又調用了上游的 subscribe(emitter) 觸發了數據的流動。

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