看完了 compose, 顺带的又 和有 lift 有了些联系,
lift 是用来 让自定义操作符的,看网上说
RxJava 都不建议开发者自定义 Operator 来直接使用 lift(),而是建议尽量使用已有的 lift() 包装方法(如 map() flatMap() 等)进行组合来实现需求,因为直接使用 lift() 非常容易发生一些难以发现的错误。
lift(Operator)
搜了一些方面的资料
http://gank.io/post/560e15be2dca930e00da1083#toc_19
http://blog.chengyunfeng.com/?p=976
在 lift 和 compose 之间做选择
lift 和 compose 都是元操作符(meta-operators),用来把自定义的操作函数注射到串联调用中。这两种情况下,自定义操作符既可以用函数实现也可以用类实现:
– compose: Observable.Transformer 或者 Func
public final <R> Observable<R> lift(Observable.Operator<? extends R,? super T> lift)
Observable.Operator
class MyMap<T,R> implements Observable.Operator<R, T> {
private Func1<T,R> transformer;
public MyMap(Func1<T,R> transformer) {
this.transformer = transformer;
}
@Override
public Subscriber<? super T> call(Subscriber<? super R> subscriber) {
return new Subscriber<T>() {
@Override
public void onCompleted() {
if (!subscriber.isUnsubscribed())
subscriber.onCompleted();
}
@Override
public void onError(Throwable e) {
if (!subscriber.isUnsubscribed())
subscriber.onError(e);
}
@Override
public void onNext(T t) {
if (!subscriber.isUnsubscribed())
subscriber.onNext(transformer.call(t));
}
};
}
}
map 操作函数需要一个参数把 T 转换为 R。上面 的实现中,transformer 干了这件事。关键点在于 call 函数的调用。我们收到了一个 Subscriber对象,该对象需要一个 R 类型数据。我们为个 Subscriber 创建了一个Subscriber 对象,并把 T 转换为 R 类型数据然后发射给 Subscriber。 lift 操作函数处理接受 Subscriber 的模板代码,并且使用 Subscriber 订阅到源 Observable上。
使用 Observable.Operator 和使用 Observable.Transformer 一样简单:
Observable.range(0, 5)
.lift(new MyMap<Integer, String>(i -> i + "!"))
.subscribe(System.out::println);
0!
1!
2!
3!
4!
就像实现 Observable.Operator 中手动把数据发射给 Subscriber 一样,需要考虑如下情况:
– Subscriber 可以随时取消订阅,所以需要检查是否还在订阅着,如果取消订阅了则不发射数据
– 你需要遵守 Rx 的约定,调用 onNext 发射数据,依 onCompleted 或者 onError 来结束数据流
– 如果需要异步处理数据或者调度,则需要使用 Rx 的 Schedulers 。这样你的操作函数将是可测试的。