RxJava2.Xソースコード分析(5):変換演算子の実現原理(オン)

I.はじめに

Rxjavaは、実際にはその変換演算子を使用するのに最適です。次に、一般的に使用される変換演算子の実装原理を分析します。演算子の分析を2つの部分に分割する予定です。簡単なマップから始めましょう。本質の後で、強力なものを分析します。 flatMap演算子。

デモからソースコードまで2つ

最初に例を見てみましょう:

Observable.create(new ObservableOnSubscribe<Integer>() {
    
    
    @Override
    public void subscribe(ObservableEmitter<Integer> e) throws Exception {
    
    
        e.onNext(1);
        e.onNext(2);
        e.onNext(3);
    }
}).map(new Function<Integer, String>() {
    
    
    @Override
    public String apply(Integer integer) throws Exception {
    
    
        return integer + "a";
    }
}).subscribe(new Consumer<String>() {
    
    
    @Override
    public void accept(String s) throws Exception {
    
    
        Log.d("map:",s);
    }
});

=================================================
结果:
2021-02-02 11:08:00.782 11974-11974/com.example.myapplication D/map:: 1a
2021-02-02 11:08:00.782 11974-11974/com.example.myapplication D/map:: 2a
2021-02-02 11:08:00.782 11974-11974/com.example.myapplication D/map:: 3a

もちろん、演算子マップによって提供される機能は間違いなくそれ以上のものです。必要なロジックコードをapplyコールバックで記述できます。

3つのソースコード分析

最初にmapメソッドから始めて、内部で何が行われたかを見てみましょう。

Class Obserable{
    
    

public final <R> Observable<R> map(Function<? super T, ? extends R> mapper) {
    
    
    ObjectHelper.requireNonNull(mapper, "mapper is null");
    return RxJavaPlugins.onAssembly(new ObservableMap<T, R>(this, mapper));
}
}

案の定、おなじみのコードはonAssemblyパラメーターのみになります。ここで注意が必要です。TはアップストリームのObservableによって発行されたデータ型、Rはダウンストリームのオブザーバーが受信するデータ型です。つまり、これを理解できます。とりあえず、TはRに変換されますが、flatMapに関しては、それほど簡単に理解することはできないので、なぜそう言うのですか。

引き続きObservableMapクラスを調べ、その継承構造を見てみましょう。これは
ここに画像の説明を挿入
まだ古い方法であり、着信ソース(observable)をラップしてから戻ります。次に、ObservableMapの特定の実装を見てみましょう。

  public final class ObservableMap<T, U> extends AbstractObservableWithUpstream<T, U> {
    
    

      final Function<? super T, ? extends U> function;

      public ObservableMap(ObservableSource<T> source, Function<? super T, ? extends U> function) {
    
    
          //1、source 为上游的Observable
          super(source);
           //2、 function 为我们传入的funcation对象
          this.function = function;
      }

      @Override
    public void subscribeActual(Observer<? super U> t) {
    
    
          //3、t为下游的Observer对象
          source.subscribe(new MapObserver<T, U>(t, function));
      }

      static final class MapObserver<T, U> extends BasicFuseableObserver<T, U> {
    
    
          final Functionsuper T, ? extends U> mapper;

          MapObserver(Observer<? super U> actual, Functionsuper T, ? extends U> mapper) {
    
    
              //4、actual 为下游的Observer
              super(actual);
              //5、mapper为我们传入的function函数对象
              this.mapper = mapper;
          }

          @Override
    public void onNext(T t) {
    
    
              if (done) {
    
    
                  return;
              }
              ...
              U v;

              try {
    
    
                  //6、调用mapper的apply方法,或者apply回调的返回值
                  v = ObjectHelper.requireNonNull(mapper.apply(t), "The mapper function returned a null value.");
              } catch (Throwable ex) {
    
    
                  fail(ex);
                  return;
              }
              //7、回调下游Obsever的onNext方法
              actual.onNext(v);
          }

        .....
      }
  }

mapメソッドによって返されるObservableラッパークラスObservableMapは、ダウンストリームObserverによってサブスクライブされ、ObservableMapのsubscribeActualメソッドが開始されます。このメソッドはダウンストリームObserverのラッパークラスであり、MapObserverはアップストリームObservableにサブスクライブし、Observableはデータを配信します。ラッパークラスMapObserverは単なる媒体です。ダウンストリームのオブザーバー参照tを介して、ダウンストリームのオブザーバーはアップストリームのObservableによって送信されたイベントを受信できます。
ここでの6番目のポイントは、デモの関数で書き直されたapply()メソッドを呼び出して、戻り値を介してさまざまなタイプの変換を実装し、ダウンストリームオブザーバーのonNextメソッドをパラメーターとして使用してコールバックすることです。最終的に変換の目的を達成します。
誰もがここで疑問に思うでしょう、なぜonError、onCompeter、およびonSubscribeメソッドが欠落しているのですか?これらは、MapObserverの親クラスBasicFuseableObserverに実装できます。

public abstract class BasicFuseableObserver<T, R> implements Observer<T>, QueueDisposable<R> {
    
    
...
public BasicFuseableObserver(Observersuper R> actual) {
    
    
        this.actual = actual;
    }
 @SuppressWarnings("unchecked")
      @Override
    public final void onSubscribe(Disposable s) {
    
    
          if (DisposableHelper.validate(this.s, s)) {
    
    
              //1、接收下游的Disposable加入管理队列
              this.s = s;
              if (s instanceof QueueDisposable) {
    
    
                  this.qs = (QueueDisposable<T>)s;
              }
              //2、可以重写onSubscribe()的回调之前做一些操作
              if (beforeDownstream()) {
    
    

                  actual.onSubscribe(this);
                //3、可重写在onSubscribe调用后做一些操作
                  afterDownstream();
              }

          }
      }


    @Override
    public void onError(Throwable t) {
    
    
          if (done) {
    
    
              RxJavaPlugins.onError(t);
              return;
          }
          done = true;
          actual.onError(t);
      }

      @Override
    public void onComplete() {
    
    
          if (done) {
    
    
              return;
          }
          done = true;
          actual.onComplete();
      }
  ...
  }

案の定、サブクラスコードを単純化するために、パブリックメソッドが親クラスに抽出されて実装されます。

4つの要約

さて、上記の分析によると、マップの操作プロセスについてはすでに非常に明確です。これは、基本的に前のスレッド切り替えの実装原理と同じです。デコレータモードを使用して、中間のObservableとObserveを中央に挿入します。 、プロキシとして想像できます。
プロキシObservableが行うことは、ダウンストリームObserverからサブスクリプションイベントを受信し、プロキシObseverを介してアップストリームObserverにサブスクライブし、アップストリームObserverがプロキシObserverにデータを送信するときに、変換されたデータは最初にマッパーを呼び出すことによって取得されます.apply変換コールバック関数を適用し、IssuedをダウンストリームObseverにダウンロードします。
わかりました、これは実際に当てはまります。デコレータパターンは、拡張機能を実現するためにRxJava2で広く使用されています。
次のパートでは、RxJava2のflatMapの高度な変換関数を分析します。

おすすめ

転載: blog.csdn.net/qq_39431405/article/details/113542645