最近发现组内有同学把Rxjava的subscribeOn跟observeOn用反,导致了线上事故,想起了自己很早写的一篇文章,今天就把这老掉牙的文章搬运到掘金来。
在使用Rxjava的时候,总是不知道该用subscribeOn还是observeOn,死记硬背不仅容易忘并且还容易记错,接下来我们从原理出发,一文搞懂这两个的区别,再也不会出错。
讲解正文之前,我们先看一下核心类图。构成了Rxjava的蛇形调用(其实就是观察者模式的变种,将观察者模式的观察者设置为另外一个观察者模式的被观察者)。
subscribeActual是Observable的核心,所有Observable的特殊实现都是在这个方法里。
示例:假设mapper与observer1里的代码是我们的业务代码。
可以看出,Rxjava在调用的过程就像下面的图形一样。侧过来看就是“S”型调用(蛇形)
第1条线:执行链式调用
第2条线:执行框架层代码与subcribeOn
第3条线:我们的核心代码,比如上图中的map与observer1
暂时无法在飞书文档外展示此内容
根据上图可以清晰的看明白,在执行我们的核心代码第3条链路之前,不管有多少个subscribeOn,只有第一个subscribeOn是生效的,而observerOn是针对下面的代码生效。
源码分析:
我们先看subscribeOn对应的代码
//Observable.java
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.CUSTOM)
public final Observable<T> subscribeOn(Scheduler scheduler) {
ObjectHelper.requireNonNull(scheduler, "scheduler is null");
return RxJavaPlugins.onAssembly(new ObservableSubscribeOn<T>(this, scheduler));
}
// ObservableSubscribeOn.java
public final class ObservableSubscribeOn<T> extends AbstractObservableWithUpstream<T, T> {
...
@Override
public void subscribeActual(final Observer<? super T> observer) {
final SubscribeOnObserver<T> parent = new SubscribeOnObserver<T>(observer);
observer.onSubscribe(parent);
parent.setDisposable(scheduler.scheduleDirect(new SubscribeTask(parent)));
}
}
//SubscribeTask.java
static final class SubscribeTask<T> implements Runnable {
final MaybeObserver<? super T> observer;
final MaybeSource<T> source;
SubscribeTask(MaybeObserver<? super T> observer, MaybeSource<T> source) {
this.observer = observer;
this.source = source;
}
@Override
public void run() {
source.subscribe(observer);
}
}
我们再看observeOn的源码
//Observable.java
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.CUSTOM)
public final Observable<T> observeOn(Scheduler scheduler, boolean delayError, int bufferSize) {
ObjectHelper.requireNonNull(scheduler, "scheduler is null");
ObjectHelper.verifyPositive(bufferSize, "bufferSize");
return RxJavaPlugins.onAssembly(new ObservableObserveOn<T>(this, scheduler, delayError, bufferSize));
}
//ObservableObserveOn.java
public final class ObservableObserveOn<T> extends AbstractObservableWithUpstream<T, T> {
...
@Override
protected void subscribeActual(Observer<? super T> observer) {
Scheduler.Worker w = scheduler.createWorker();
source.subscribe(new ObserveOnObserver<T>(observer, w, delayError, bufferSize);
}
}
从代码上可以看到,subscribeOn 与 observeOn的主要区别就是,subscribeOn先切换了线程再执行的source.subscribe(这个方法是向上回溯的,每个observable都会调用,只有这个方法执行完之后,才会执行我们自己的代码)。