RxJava 源码解读分析 flatMap

这一节,我们重点来分析RxJava.flatMap()方法内部是如何实现的

先上一段测试代码,如下所示:

@Test
    public void test2() throws InterruptedException {
        Observable.create(new Observable.OnSubscribe<Integer>() {
            @Override
            public void call(Subscriber<? super Integer> subscriber) {
                log.debug("step1, original onSubscribe.call(), hello, rxjava");
                subscriber.onNext(1);
                subscriber.onNext(2);
                subscriber.onCompleted();
            }
        }).flatMap(new Func1<Integer, Observable<String>>() {
            @Override
            public Observable<String> call(Integer integer) {
                log.debug("step2, func1.call(), return an new observable, in={}", integer);
                return Observable.create(new Observable.OnSubscribe<String>() {
                    @Override
                    public void call(Subscriber<? super String> subscriber) {
                        log.debug("step3, func1.observable.call(), in={}", integer);
                        for(int i = 0; i < 2; i++){
                            String out = integer + "_" + i;
                            subscriber.onNext(out);
                        }
                    }
                });
            }
        }).subscribe(new Subscriber<String>() {
            @Override
            public void onCompleted() {
                log.debug("Subscriber1, onCompleted event");
            }

            @Override
            public void onError(Throwable throwable) {
                log.error("Subscriber1, onError event", throwable);
            }

            @Override
            public void onNext(String v) {
                log.debug("step4, Subscriber1, onNext event, value={}", v);
            }
        });

        Thread.sleep(1000*2);
    }

事实上RxJava源代码写的很绕,可以用“余音绕梁”来形容,个人感觉是,不好理解,真的不好理解,没有点耐心,是读不来的。
我们先声明几行代码的含义,以让大家好理解。

---A1, RxJavaHooks.onObservableLift(operator).call(o);
------可以直接理解为调用operator.call()方法
---A2, source.unsafeSubscribe(parent);//source是个Observable<T>
------可以直接理解为,有订阅者了,马上要执行Observable.OnSubscribe.call()方法,而Observable.OnSubscribe.call()内部紧接者马上要调用subscriber.onNext()方法。
---A3, parent.call(st);//parent是个OnSubscribe<T>, st是个Subscriber
------A3和A2其实是一样的,相比A2,少了Observable,直接调用OnSubscribe.call(Subscriber)方法,紧接者马上会调用subsriber.onNext()方法。
---A4, RxJavaHooks.onObservableStart(observable, observable.onSubscribe).call(subscriber);
------可以直接理解为调用onSubscribe.call()方法。


有了以上的理解,我们再来看一看flatMap的部分源代码。
public final <R> Observable<R> flatMap(Func1<? super T, ? extends Observable<? extends R>> func) {
if (getClass() == ScalarSynchronousObservable.class) {
return ((ScalarSynchronousObservable<T>)this).scalarFlatMap(func);
}
return merge(map(func));
}
public final <R> Observable<R> map(Func1<? super T, ? extends R> func) {
return create(new OnSubscribeMap<T, R>(this, func));
}
OnSubscribe包装为OnSubscribeMap
public static <T> Observable<T> merge(Observable<? extends Observable<? extends T>> source) {
if (source.getClass() == ScalarSynchronousObservable.class) {
return ((ScalarSynchronousObservable<T>)source).scalarFlatMap((Func1)UtilityFunctions.identity());
}
return source.lift(OperatorMerge.<T>instance(false));
}
public final <R> Observable<R> lift(final Operator<? extends R, ? super T> operator) {
return create(new OnSubscribeLift<T, R>(onSubscribe, operator));
}
OnSubscribeMap被包装为OnSubscribeLift
就这样,Observable和OnSubscribe被一层一层的包装了,实际上只是包装了OnSubscribe,用来生成新的observable。


我们前几篇文章也经分析过了,observable.subscribe(subscriber)方法,最终会调用如下:
RxJavaHooks.onObservableStart(observable, observable.onSubscribe).call(subscriber);
也就是直接调用onSubscribe.call()方法,而call()方法内部也一般会调用onNext()等方法。
根据上面的分析,OnSubscribe最终被包装为OnSubscribeLift,
OnSubscribeLift.call(){
Subscriber<? super T> st = RxJavaHooks.onObservableLift(operator).call(o);
try {
// new Subscriber created and being subscribed with so 'onStart' it
st.onStart();
parent.call(st);
}
}
这里的o是原始的subscriber,
这里的parent是onSubscribeMap
这里的st是原始subscriber的包装,具体类型是MergeSubscriber

再看OperatorMerge.call()方法,如下:
public Subscriber<Observable<? extends T>> call(final Subscriber<? super T> child) {
MergeSubscriber<T> subscriber = new MergeSubscriber<T>(child, delayErrors, maxConcurrent);
MergeProducer<T> producer = new MergeProducer<T>(subscriber);
subscriber.producer = producer;


child.add(subscriber);// 这里的child就是原始的subscriber
child.setProducer(producer);


return subscriber;
}

分析到这里,大家应该能明白了吧,知道怎么看剩下的代码了吧。
最后还是决定写一五后面的方法调用过程,我还是担心大部分人会看晕。。。

Observable.subscribe(Subscriber<? super T> subscriber)
RxJavaHooks.onObservableStart(observable, observable.onSubscribe).call(subscriber);//onSubscribe实际类型是OnSubscribeLift
OnSubscribeLift.call()方法如下:
public void call(Subscriber<? super R> o) {
...
Subscriber<? super T> st = RxJavaHooks.onObservableLift(operator).call(o);
//operatoro具体类型是OperatorMerge
//o是原始的subscriber
//st具体类型是MergeSubscriber

try {
// new Subscriber created and being subscribed with so 'onStart' it
st.onStart();
parent.call(st);//parent是OnSubscribeMap
}
...
}
OperatorMerge.call()方法如下
public Subscriber<Observable<? extends T>> call(final Subscriber<? super T> child) {
MergeSubscriber<T> subscriber = new MergeSubscriber<T>(child, delayErrors, maxConcurrent);
MergeProducer<T> producer = new MergeProducer<T>(subscriber);
subscriber.producer = producer;


child.add(subscriber);
child.setProducer(producer);


return subscriber;
}
parent.call(st);也就是OnSubscribeMap.call(),方法如下:
public void call(final Subscriber<? super R> o) {//参数o具体类型是MergeSubscriber
MapSubscriber<T, R> parent = new MapSubscriber<T, R>(o, transformer);
o.add(parent);
source.unsafeSubscribe(parent);//注意参数parent,这时候是MapSubscriber, source就是我们自己写的原始的observable代码,就是step1那段代码
}
step1那段代码中,紧接着就调用了subscriber.onNext()方法,也就是调用MapSubscriber.onNext(),代码如下
public void onNext(T t) {
R result;


try {
result = mapper.call(t);//mapper也就是func1, mapper.call()就是调用step2那段代码,产生一个新的observable
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
unsubscribe();
onError(OnErrorThrowable.addValueAsLastCause(ex, t));
return;
}


actual.onNext(result);//actual具体类型是MergeSubscriber,也就是调用MergeSubscriber.onNext()方法
}
MergeSubscriber.onNext()方法,如下:
public void onNext(Observable<? extends T> t) {//注意这里的参数类型是observable
if (t == null) {
return;
}
if (t == Observable.empty()) {
emitEmpty();
} else
if (t instanceof ScalarSynchronousObservable) {
tryEmit(((ScalarSynchronousObservable<? extends T>)t).get());
} else {//代码会走到这个分支里
InnerSubscriber<T> inner = new InnerSubscriber<T>(this, uniqueId++);
addInner(inner);
t.unsafeSubscribe(inner);//这里的t就是func1里创建出来的新的observable,也就异味着要执行step3这段代码了,请读者想想为啥?
emit();
}
}
紧接者会调用inner.onNext(),请读者想想为啥,代码如下
public void onNext(T t) {
parent.tryEmit(this, t);
}
parent.tryEmit()方法如下:
void tryEmit(InnerSubscriber<T> subscriber, T value) {
boolean success = false;
long r = producer.get();
if (r != 0L) {
synchronized (this) {
// if nobody is emitting and child has available requests
r = producer.get();
if (!emitting && r != 0L) {
emitting = true;
success = true;
}
}
}
if (success) {
RxRingBuffer subscriberQueue = subscriber.queue;
if (subscriberQueue == null || subscriberQueue.isEmpty()) {
emitScalar(subscriber, value, r);//代码会走到这里
} else {
queueScalar(subscriber, value);
emitLoop();
}
} else {
queueScalar(subscriber, value);
emit();
}
}
emitScalar()方法如下:
protected void emitScalar(InnerSubscriber<T> subscriber, T value, long r) {
boolean skipFinal = false;
try {
try {
child.onNext(value);//重点在这里,child就是原始的subscriber,step4那段代码
} catch (Throwable t) {
if (!delayErrors) {
Exceptions.throwIfFatal(t);
skipFinal = true;
subscriber.unsubscribe();
subscriber.onError(t);
return;
}
getOrCreateErrorQueue().offer(t);
}
if (r != Long.MAX_VALUE) {
producer.produced(1);
}
subscriber.requestMore(1);
// check if some state changed while emitting
synchronized (this) {
skipFinal = true;
if (!missed) {
emitting = false;
return;
}
missed = false;
}
} finally {
if (!skipFinal) {
synchronized (this) {
emitting = false;
}
}
}
/*
* In the synchronized block below request(1) we check
* if there was a concurrent emission attempt and if there was,
* we stay in emission mode and enter the emission loop
* which will take care all the queued up state and
* emission possibilities.
*/
emitLoop();//这段代码估计是想把并发emit的数据尽快的的emit出去,防止数据堆积用的,从英文的注释中看,大概是这个意思
}

flatMap操作符,是将输入T转换成obserbable<R>,再由这个observable<R>发射具体类型是R的数据,有意思的是,经过这个Observable<R>,就可以由原来的一个数据项T变为再多个数据项R,由subscriber消费类型为R的所有数据项。

而map操作符,是将输入T直接转换成R,再由subscriber消息类型为R的数据项。

猜你喜欢

转载自blog.csdn.net/collonn/article/details/71486642