本文使用Rxjava1.0实例,重在研究思想和原理。
Observable> observable = Observable.create(new Observable.OnSubscribe>() {
@Override
public void call(Subscriber super HttpResult
func1:
public interface Func1<T, R> extends Function {
R call(T t);
}
func1 《T,R》 的工作就是T-》R的转换;
Operator
public interface Operator<R, T> extends Func1<Subscriber super R>, Subscriber super T>> {
// cover for generics insanity
}
Operator 是Func1的子类,做的工作是把一个Subscriber R转化成另外一个Subscriber T。
Observer:
public interface Observer {
/**
* Notifies the Observer that the {@link Observable} has finished sending push-based notifications.
*
* The {@link Observable} will not call this method if it calls {@link #onError}.
*/
void onCompleted();
/**
* Notifies the Observer that the {@link Observable} has experienced an error condition.
*
* If the {@link Observable} calls this method, it will not thereafter call {@link #onNext} or
* {@link #onCompleted}.
*
* @param e
* the exception encountered by the Observable
*/
void onError(Throwable e);
/**
* Provides the Observer with a new item to observe.
*
* The {@link Observable} may call this method 0 or more times.
*
* The {@code Observable} will not call this method again after it calls either {@link #onCompleted} or
* {@link #onError}.
*
* @param t
* the item emitted by the Observable
*/
void onNext(T t);
观察者类,回调给观察者。
Subscriber:
public abstract class Subscriber implements Observer, Subscription
Subscription :
public interface Subscription {
/**
* Stops the receipt of notifications on the {@link Subscriber} that was registered when this Subscription
* was received.
*
* This allows unregistering an {@link Subscriber} before it has finished receiving all events (i.e. before
* onCompleted is called).
*/
void unsubscribe();
/**
* Indicates whether this {@code Subscription} is currently unsubscribed.
*
* @return {@code true} if this {@code Subscription} is currently unsubscribed, {@code false} otherwise
*/
boolean isUnsubscribed();
}
很明显,是Observer类的扩充,加了Subscription的解订阅能力。
public final Observable map(Func1 super T, ? extends R> func) {
return lift(new OperatorMap(func));
}
关键在lift:
public final Observable lift(final Operator extends R, ? super T> operator) {
return **1**new Observable(**2**new OnSubscribe() {
@Override
public void call(Subscriber super R> o) {
try {
**3**Subscriber super T> st = hook.onLift(operator).call(o);
try {
// new Subscriber created and being subscribed with so 'onStart' it
**4**st.onStart();
**5**onSubscribe.call(st);
} catch (Throwable e) {
// localized capture of errors rather than it skipping all operators
// and ending up in the try/catch of the subscribe method which then
// prevents onErrorResumeNext and other similar approaches to error handling
Exceptions.throwIfFatal(e);
st.onError(e);
}
} catch (Throwable e) {
Exceptions.throwIfFatal(e);
// if the lift function failed all we can do is pass the error to the final Subscriber
// as we don't have the operator available to us
o.onError(e);
}
}
});
}
OnSubscribe
public interface OnSubscribe<T> extends Action1<Subscriber super T>> {
// cover for generics insanity
}
OnSubscribe 做的事,就是拿到Subscriber,开始发送流程。
分析下
看1,原来并没有用原来的Observable,而是新new了一个;
2,new的Observable没有用之前的OnSubscribe,也是new 了一个,这个OnSubscribe 后面会在subscribe调用的时候使用;
3,hook.lift;hook这里是个默认实现,返回的结果仍是operator,然后调用operator.call(o),这个o是OnSubscribe.call调用的时候传过来的,上面说了,operator做的事,就是把一个Subscriber转成另一个Subscriber。
看下Map操作的operator,OperatorMap的实现:
public final class OperatorMap<T, R> implements Operator<R, T> {
private final Func1 super T, ? extends R> transformer;
public OperatorMap(Func1 super T, ? extends R> transformer) {
this.transformer = transformer;
}
@Override
public Subscriber super T> call(final Subscriber super R> o) {
return new Subscriber(o) {
@Override
public void onCompleted() {
o.onCompleted();
}
@Override
public void onError(Throwable e) {
o.onError(e);
}
@Override
public void onNext(T t) {
try {
o.onNext(transformer.call(t));
} catch (Throwable e) {
Exceptions.throwOrReport(e, this, t);
}
}
};
}
}
operator做的事,就是把一个Subscriber转成另一个Subscriber,没毛病,OperatorMap把构造函数依赖的Fucn1用在了从Subscriber o 到 返回的Subscriber 的转换关系中,在这个时候,新的Subscriber o.next(T t)中回调的t是被func1定义转换规则的、转换后的新对象。在这一步就完成了转换。
回过头来看3,其实hook.onLift(operator).call(o)返回的就已经是转换过的Subscriber;
4、转换过的Subscriber.onStart();
5、之前Observable创建的OnSubscribe 执行事件流。这个地方,新的Observable新的OnSubscribe确用了之前的OnSubscribe,也就是说,转换之后的Subscriber传递到了上层。伪代码如下;
new Observable(onSubscribe){
OnSubscribe old = onSubscribe;
lift(){
new Observable(new OnSubscribe{
call(subscriber){
//doSomeThing...例如通过Opertor转换成新的subscriber 起个名叫newSubscriber
old.call(newSubscriber);
//doSomeThing...
}
}//这个new的OnSubscribe 起个名叫onSubscribe1){
OnSubscribe old1= onSubscribe1;
lift(){
//...一直重复
}
}
}
}
所以调用n次lift,就会有n个Observable,n个OnSubscribe,n次转换,下一层会持有上一层的OnSubscribe引用,在每一层的call方法中装饰上一层(old)OnSubscribe,装饰的过程是用operator对subscriber进行转换subscriber(newSubscriber),会通过上一层(old)OnSubscribe的call方法传给上一个(old)Observable
,一直递归上去直到最开始的OnSubscribe,也就是我们的事件开始流。
再看下subscribe的动作。
private static Subscription subscribe(Subscriber super T> subscriber, Observable observable) {
// validate and proceed
if (subscriber == null) {
throw new IllegalArgumentException("observer can not be null");
}
if (observable.onSubscribe == null) {
throw new IllegalStateException("onSubscribe function can not be null.");
/*
* the subscribe function can also be overridden but generally that's not the appropriate approach
* so I won't mention that in the exception
*/
}
// new Subscriber so onStart it
subscriber.onStart();
/*
* See https://github.com/ReactiveX/RxJava/issues/216 for discussion on "Guideline 6.4: Protect calls
* to user code from within an Observer"
*/
// if not already wrapped
if (!(subscriber instanceof SafeSubscriber)) {
// assign to `observer` so we return the protected version
subscriber = new SafeSubscriber(subscriber);
}
// The code below is exactly the same an unsafeSubscribe but not used because it would
// add a significant depth to already huge call stacks.
try {
// allow the hook to intercept and/or decorate
**6**hook.onSubscribeStart(observable, observable.onSubscribe).call(subscriber);
return hook.onSubscribeReturn(subscriber);
} catch (Throwable e) {
// special handling for certain Throwable/Error/Exception types
Exceptions.throwIfFatal(e);
// if an unhandled error occurs executing the onSubscribe we will propagate it
try {
subscriber.onError(hook.onSubscribeError(e));
} catch (Throwable e2) {
Exceptions.throwIfFatal(e2);
// if this happens it means the onError itself failed (perhaps an invalid function implementation)
// so we are unable to propagate the error correctly and will just throw
RuntimeException r = new RuntimeException("Error occurred attempting to subscribe [" + e.getMessage() + "] and then again while trying to pass to onError.", e2);
// TODO could the hook be the cause of the error in the on error handling.
hook.onSubscribeError(r);
// TODO why aren't we throwing the hook's return value.
throw r;
}
return Subscriptions.unsubscribed();
}
}
这个代码看起来有点多,其实是纸老虎。
先看入参:subscriber,就是我们自己接收回调的subscriber;observable传的是this,也就是调用subscribe方法的observable,如上面所说,每次lift之后都是一个新的Observable、新的OnSubscribe。
再看6,hook.onSubscribeStart(observable, observable.onSubscribe).call(subscriber) 的默认实现最后还是走了
observable.onSubscribe.call(subscriber);这个时候就回到了lift里面的3,也就是说,这个subscriber 就是lift中的o(old subscriber),在call中,被operatormap 通过Func1装饰成了st。而在lift操作中的onSubscribe.call中,新的onSubscribe开始事件流。
再理一下过程:
1、当我们使用Observable 的subcribe方法的时候,会传一个接收回调的(下游)subscriber o;
2、Observable 会调用用它的成员OnSubscribe 的call方法;
3、这个call方法,其实就是在map操作时lift new 的OnSubscribe的call方法,也就是说这个new出来的OnSubscribe就是2中使用的;
4、call方法中,把subscriber o 通过operatorMap中的func1转成了subscriber st;
5、用上一层的OnSubscribe继续调用call(丢给上游装饰),再此转化,直至到最顶层。
至此,完成了上下游的切换。简单总结,就是从下游开始,每次lift都在不断装饰,直到丢给最上层的用来发送事件流的OnSubscribe是完成所有转换规则的OnSubscribe。
总结一下这个过程的设计模式,上面提到了多次“装饰”,没错,很多地方都是用装饰者模式装饰,也就是所谓的转换操作;然后lift一层一层装饰处理,中间甚至可以拦截,整体思想有点类似责任链。