您的位置:首页 > 编程语言 > Java开发

RxJava 系列之变换操作符map(2)

2017-06-08 15:18 477 查看
上一篇文章中我们详细介绍了RxJava的一些常见的使用方法,只是很简单的基础使用,这边文章中我们一起来学习下RxJava更高深的使用方法。

什么是操作符?

操作符是为了解决对Observable对象的变换的问题,操作符用于在Observable和最终的Subscriber之间修改Observable发出的事件。RxJava提供了很多很有用的操作符。

map()操作符就是用于变换Observable对象的,map操作符返回一个Observable对象,这样就可以实现链式调用,在一个Observable对象上多次使用map操作符,最终将最简洁的数据传递给Subscriber对象。

可能这样解释大家还不是很容易理解,下面举个例子,大家就明白了。

怎么使用?

比如我们现在有一个需求,有一个String数组,我们利用RxJava遍历的时候,我们要对数组中每个元素都转成Integer类型,这时候我们的map操作符就很有用了。

String[] nums = new String[]{"1", "2", "3"};
Subscriber subscriber = new Subscriber<Integer>() {
@Override
public void onCompleted() {
Log.e(TAG, "onCompleted");
}

@Override
public void onError(Throwable e) {
Log.e(TAG, "onError");
}

@Override
public void onNext(Integer integer) {
Log.e(TAG, "onNext , integer = " + integer);
}
};

Observable.from(nums).map(new Func1<String, Integer>() {
@Override
public Integer call(String s) {
return Integer.parseInt(s);
}
}).subscribe(subscriber);


logcat如下:

06-08 14:44:40.103 6775-6775/com.example.boguang.demo E/RxAndroidActivity: onNext , integer = 1
06-08 14:44:40.103 6775-6775/com.example.boguang.demo E/RxAndroidActivity: onNext , integer = 2
06-08 14:44:40.103 6775-6775/com.example.boguang.demo E/RxAndroidActivity: onNext , integer = 3
06-08 14:44:40.103 6775-6775/com.example.boguang.demo E/RxAndroidActivity: onCompleted


分析下上面的代码:

当我们调用
Observable.from(nums)
的时候,这时候返回给我们的其实是
Observable<String>
类型

当我们调用map方法的时候,这时候返回给我们的就是
Observable<Integer>
类型了,也就是RxJava在map操作内部偷偷的给我们变换了类型,可谓是偷龙转凤

那map操作的原理是什么呢?

源码解析

既然map操作符这么神奇,那我们就从源码的角度看看他是怎么做到的。map内部代码:

public final <R> Observable<R> map(Func1<? super T, ? extends R> func) {
return unsafeCreate(new OnSubscribeMap<T, R>(this, func));
}


unsafeCreate方法代码:

public static <T> Observable<T> unsafeCreate(OnSubscribe<T> f) {
return new Observable<T>(RxJavaHooks.onCreate(f));
}


从上面代码可见,map方法就一行代码,就是创建了
Observable
对象,关键在实例化了
OnSubscribeMap
,实例化
OnSubscribeMap
需要两个参数,一个是当前对象,也就是我们上面说的第一步的
Observable<String>
,第二个参数就是我们传进来的func。

OnSubscribeMap
内部做了什么事情呢?

其实
OnSubscribeMap
是继承自
OnSubscribe
,所以当遍历的时候就会先执行到
OnSubscribeMap
的call方法,call方法代码如下:

MapSubscriber<T, R> parent = new MapSubscriber<T, R>(o, transformer);
o.add(parent);
source.unsafeSubscribe(parent);


上面代码的source其实就是我们
Observable<String>
,也就是from操作返回Observable,transformer也就是map传递的参数Func1,这里
MapSubscriber
对Func1进行了包装,
MapSubscriber
其实是一个
Subscriber
,所以当调用onNext方法的时候,其实先会调用
MapSubscriber
的onNext,同理,onError和onComplete,接下来看看
MapSubscriber
的onNext内部实现:

先列出其构造方法:

public MapSubscriber(Subscriber<? super R> actual, Func1<? super T, ? extends R> mapper) {
this.actual = actual;
this.mapper = mapper;
}


上面的actual其实就是我们在上面例子中subscribe方法传递的subscriber对象,mapper也就是我们map方法中参数Func1。

@Override
public void onNext(T t) {
R result;

try {
result = mapper.call(t);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
unsubscribe();
onError(OnErrorThrowable.addValueAsLastCause(ex, t));
return;
}

actual.onNext(result);
}


当订阅者收到onNext事件的时候,我们首先会调用到
MapSubscriber
中的onNext方法,也就是上面那一段代码,在这段代码内部,首先调用了,
result = mapper.call(t)
,然后把map方法内部处理后的结果传递到subscriber的onNext方法
actual.onNext(result)
,也就这样整个流程就完成了。

通过上面的分析,应该很清楚的说明了map操作的原理。map操作符其实就是对订阅者进行包装,有点类似拦截操作的意思,其实就是装饰者设计模式。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: