上次主要讲了最基本的from与just源码,今天我们主要讲的是RxJava中转换符map的使用与实现的原理。

首先我们先上一段超级简单的方法。看下图:

RxJava 场景 rxjava map_方法调用

这个函数,我们可以很清楚的知道最后打印出来的内容是“圆圆”,“袁斌”,接下来再来看一个简单的函数:

RxJava 场景 rxjava map_方法调用_02


这个函数,我们通过观察可以知道打印出来的是5和5。

那么RxJava是怎么实现把一个对象通过map函数转换成一个name字符串的,hello转换成length的呢?

其实它是这样的

1:create函数,我们会用一个变量OnSubscribe来保存create方法传入的一个匿名函数,我们在这里暂且叫他是OnSubscribe1,create创建完成之后,返回了一个新的Observable,我们先叫他为Observable1,防止后面混淆,调用map函数的时候,其实是observable1调用的,在map函数中,传入了一个function,我们来看它的具体的源码,如下:

RxJava 场景 rxjava map_RxJava 场景_03


在这个函数中,看到了一个新的对象OperateMap,这个类实现了Operator接口,而Operator又是继承自Fun1,所以它有一个call方法,

我们调用map函数的时候,只是在OperatorMap中保存了对当前函数的的引用,当调用lift的时候,

RxJava 场景 rxjava map_RxJava_04

可以看到,入参是一个OperateMap对象,出参也是new了一个Observable,我们暂且说它是Observable2,同时Observable2中的OnSubscribe2保存了lift函数中OnSubscribe的引用,

当调用了subscribe方法的时候,就是我们有订阅者订阅的时候,

如下图:

RxJava 场景 rxjava map_RxJava 场景_05


当上面那个方法调用的时候,其实这个方法的onSubscribe是OnSubscribe2,也就是说是OnSubscribe2.call(Observer),这个Observer是我们在subscribe方法中传入的订阅者,call方法一执行,就会调用到lift方法里面的call方法,Subscriber<? super T> st = hook.onLift(operator).call(o);这个方法,入参o是还是我们自己new 出来的observer,也就是说调用了OperateMap中的call方法。

如下图:

RxJava 场景 rxjava map_源码_06


这个方法返回了一个新的Subscriber2,

onSubscribe.call(st2)

把当前的Subscriber2作为入参,调用了OnSubscribe1的call方法,也就是我们在create中自己写的方法,而从观察可以看到,我们自己写的方法中,入参是Subscriber2,所以会调用到OperateMap中的onNext的方法,onNext方法会获取map函数中func转换后的值,传给我们写的Observer,这样就完成了map的转换
下面我们来梳理下具体的执行的过程:
1:create方法创建了Observable1,OnSubscribe1
2:map方法,保存fun的引用,创建了Observable2和OnSubsribe2
3:subscribe方法,创建了Subscriber1,调用了OnSubscribe2中的call方法,并把Subscriber1作为入参传入。返回subscriber2.
4:调用OnSubscribe1中的call方法,并把subscriber2传入,
5:调用subscriber2的onNext的方法,
6:调用subscribe1中的方法。

刚开始感觉这样看着头痛,一万个不舒服, 现在好多了,哈哈,相信你也是可以的。