RxJava2.X源码分析(五):变换操作符的实现原理(上)

一 前言

Rxjava最好用的其实还是它的变换操作符,接下来我们来剖析一下常用的变换操作符的实现原理;操作符的分析我打算是分成两篇学习,先从简单的map入手,当了解其本质后再分析强大的flatMap操作符。

二 从Demo到源码

我们先来看一个例子:

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

当然,操作符map提供的能力肯定不止这样,你可以的apply回调里面编写需要的逻辑代码。

三 源码分析

我们先从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为下游Observer将要接收的数据类型,也就是说,暂时我们可以这样理解,T转换为R,为什么这样说呢,因为到flatMap时,就不能这样简单的理解了。

我们继续来看ObservableMap这个类,看看它的继承结构:
在这里插入图片描述
还是老套路了,包装传入的source(被观察者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这个包装类只是媒介,通过下游Observer引用t,实现了下游Observer对上游Observable下发事件的接收。
第六点这里就调用了demo里function中重写的方法apply()方法,通过返回值实现了不同类型的转换接着作为参数回调下游Observer的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();
      }
  ...
  }

果然,为了简化子类代码,这里对公共的方法抽取到了父类里实现了。

四 总结

Ok,根据上面的分析,其实对于map的操作过程我们已经很清楚了,其跟之前的线程切换的实现原理基本一样,通过在中间使用装饰者模式插入一个中间的Observable和Observe,你可以想象为代理。
代理Observable做的事就是接收下游Obsever的订阅事件,然后通过代理Obsever订阅上游Observer,然后在上游Observer下发数据給代理Observer时,通过先调用mapper.apply转换回调函数获得转换后的数据,然后下发给下游Obsever。
Ok,其实就是这样,在RxJava2中大量运用装饰者模式来实现扩展功能。
RxJava2的flatMap高级转换函数我们将再下篇进行分析。

猜你喜欢

转载自blog.csdn.net/qq_39431405/article/details/113542645