接着上一篇博客继续分析。
Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter emitter) throws Exception {
emitter.onNext("hello");
}
}).map(new Function() {
@Override
public String apply(String s) throws Exception {
return "abc-"+s;
}
}).map(new Function() {
@Override
public String apply(String s) throws Exception {
return s+"-def";
}
}).subscribe(new Consumer() {
@Override
public void accept(String s) throws Exception {
System.out.println("result:"+s);
}
});
我们来看看添加了map操作后的subscribe有些什么变化?
public final class ObservableMap extends AbstractObservableWithUpstream {
final Function super T, ? extends U> function;
public ObservableMap(ObservableSource source, Function super T, ? extends U> function) {
super(source);
this.function = function;
}
@Override
public void subscribeActual(Observer super U> t) {
source.subscribe(new MapObserver(t, function));
}
...
当我们到达最后一个observable的时候,它是一个ObservableMap类型的Observable,因为AbstractObservableWithUpstream类继承了Observable类。
abstract class AbstractObservableWithUpstream extends Observable implements HasUpstreamObservableSource {
我们调用subscribe方法,最后都会调用到Observable抽象类子类的实现方法subscribeActual();我们来重点关注下,它做了些什么。它与最开头的ObservableCreate方法中的subscribeActual()有啥不同的。
可以看到ObservableMap中的subscribeActual()方法把调用交给了source.subscribe()方法,而source是什么?在上篇文章中分析了,是当前observable实例,也是链式的upstream上个节点。也就说交给了第一个ObservableMap的subscribe()方法,
怎么闻到了一丝递归调用的味道?
这里通过不断调用 [上个Observable].subscribe()找到第一个节点,也就是我们通过Observable.create()构造的observable,来看看这个类的subscribeActual()
public final class ObservableCreate extends Observable {
final ObservableOnSubscribe source;
public ObservableCreate(ObservableOnSubscribe source) {
this.source = source;
}
@Override
protected void subscribeActual(Observer super T> observer) {
CreateEmitter parent = new CreateEmitter(observer);
observer.onSubscribe(parent);
try {
source.subscribe(parent);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
parent.onError(ex);
}
}
虽然这个类中也看到了类似source.subscribe()方法,但是这里的source已经没有更早的节点了。所以也就是我们传入的ObservableOnSubscribe接口的实现类。
总结一下:在observable链中,subscribe()方法会一直递归,追溯到最原始的起点处,然后再调用其subscribe()方法。
其实知道这一点对于subscribeOn()的线程切换就可以了解到一点了。这个后续写线程切换原理系列再来讨论。
接着,我们分析一下Observer链是怎么形成的?
我们先看一下每加入一个map操作符,observer的构造发生了怎样的变化。先看第一个map的操作符的subscribeActual()方法。
public void subscribeActual(Observer super U> t) {
source.subscribe(new MapObserver(t, function));
}
这里把之前从Consumer创建的LambdaObserver传进来,作为构造函数的参数传给了MapObserver,并传给了父类的构造函数。
static final class MapObserver extends BasicFuseableObserver {
final Function super T, ? extends U> mapper;
MapObserver(Observer super U> actual, Function super T, ? extends U> mapper) {
super(actual);
this.mapper = mapper;
}
@Override
public void onNext(T t) {
...
downstream.onNext(v);
}
...
}
MapObserver继承的BasicFuseableObserver也继承于Observer,lambdaObserver赋值给了downStream对象。
public abstract class BasicFuseableObserver implements Observer, QueueDisposable {
/** The downstream subscriber. */
protected final Observer super R> downstream;
...
public BasicFuseableObserver(Observer super R> downstream) {
this.downstream = downstream;
}
...
}
可以看到MapObserver在OnNext()方法中,最终又调用了downstream的onNext()方法,MapObserver,LambdaObserver都继承于Observer,这里很明显,对方法进行了增强,同时又持有了当前的Observer作为下一个被调用的节点。既使用到了装饰者模式,又是一种责任链。当最上层的emitter吐数据的时候,优先调用了当前Observer的onNext(),等到执行完后,再开始调用下一个Observer的onNext(),这样达到了层层传递,层层处理的目的。
我们还可以继续看一下其它操作符,他们是不是也是类似的一套流程:
看看FlatMap的:
public final class ObservableFlatMap extends AbstractObservableWithUpstream {
...
public ObservableFlatMap(ObservableSource source,
Function super T, ? extends ObservableSource extends U>> mapper,
boolean delayErrors, int maxConcurrency, int bufferSize) {
super(source);
...
}
@Override
public void subscribeActual(Observer super U> t) {
...
source.subscribe(new MergeObserver(t, mapper, delayErrors, maxConcurrency, bufferSize));
}
static final class MergeObserver extends AtomicInteger implements Disposable, Observer {
final Observer super U> downstream;
...
MergeObserver(Observer super U> actual, Function super T, ? extends ObservableSource extends U>> mapper,
boolean delayErrors, int maxConcurrency, int bufferSize) {
...
}
...
@Override
public void onNext(T t) {
...
subscribeInner(p);
}
void subscribeInner(ObservableSource extends U> p) {
...
if (tryEmitScalar(((Callable extends U>)p)) && maxConcurrency != Integer.MAX_VALUE) {
...
} ...
}
}
...
boolean tryEmitScalar(Callable extends U> value) {
...
if (get() == 0 && compareAndSet(0, 1)) {
downstream.onNext(u);
...
} else {
...
}
}
其中省掉了很多无关分析的代码,首先subscribeActual()的时候一样会对上一个observable进行追溯。
在构造Observer的时候呢,一样采用装饰者模式把当前节点作为下一个节点添加到新的Observer中。
MergeObserver的onNext方法中一样是先执行自己的内容,最后又通过两层调用,回到了downStream下游节点这个Observer的onNext()方法。可见套路非常类似。有点像ViewGroup事件拦截的冒泡方式,只不过刚好相反,这个先浮上来,再沉下去。
在subscribe()逆向执行的过程中,也形成了一条正向Observer链条,这样当追根溯源到起始的Emitter开始吐数据时,后面的onNext都按照责任链,一步一步走下去。
一旦明白了observable与observer这两条链路关系后,RxJava的框架就比较清晰了,线程切换原理更容易理解。因为observeOn(),subscribeOn()也被封装成了类似的一套处理流程。后面再写文章来分析一下。