RxJava ,lift()

pdog發表於2018-01-23
@CheckReturnValue
    @BackpressureSupport(BackpressureKind.SPECIAL)
    @SchedulerSupport(SchedulerSupport.NONE)
    public final <R> Flowable<R> lift(FlowableOperator<? extends R, ? super T> lifter) {
        ObjectHelper.requireNonNull(lifter, "lifter is null");
        return RxJavaPlugins.onAssembly(new FlowableLift<R, T>(this, lifter));
    }
複製程式碼

關鍵程式碼

    public final <R> Flowable<R> lift(FlowableOperator<? extends R, ? super T> lifter) {
        return new FlowableLift<R, T>(this, lifter);
    }
複製程式碼

函式返回了一個FlowableLift物件。

public final class FlowableLift<R, T> extends AbstractFlowableWithUpstream<T, R> {

    final FlowableOperator<? extends R, ? super T> operator;

    public FlowableLift(Flowable<T> source, FlowableOperator<? extends R, ? super T> operator) {
        super(source);
        this.operator = operator;
    }

    @Override
    public void subscribeActual(Subscriber<? super R> s) {
       //...
       Subscriber<? super T> st = operator.apply(s);
       //...
       source.subscribe(st);
       //...
}
複製程式碼

public FlowableLift(Flowable<T> source...
source = Flowable-1
FlowableLift = Flowable-2

public void subscribeActual(Subscriber<? super R> s) {
Subscriber<? super T> st = operator.apply(s);
s = Subscriber-1
st = Subscriber-2
複製程式碼

此時有兩個Flowable,(原始的和 return建立的)。[Flowable-1,Flowable-2]

當呼叫lift()之後物件的subscribe()方法時,呼叫的是return建立的Flowable-2#subscriber(),於是它觸發了 source.subscribe(st) 此時source是原始的Flowable-1物件,而st是通過operator.apply(s)生成的Subscriber-2物件。[Subscriber-1,Subscriber-2]

operator通過call方法將原始的Subcsriber-1物件變換成了一個新的Subscriber-2

然後將新的Subscriber-2物件與原始的Flowable-1物件關聯起來source.subscribe(st);

這樣就實現了lift()的過程

lift()IntegerString

  Flowable<Integer> flowable = Flowable.create(e -> {
            Timber.d("e = %s", e.getClass().getSimpleName());
            e.onNext(0);
            e.onNext(1);
            e.onNext(2);
            e.onNext(3);
            e.onComplete();
        }, BackpressureStrategy.MISSING);

        Flowable<String> lift = flowable.lift(observer -> new Subscriber<Integer>() {
            @Override
            public void onSubscribe(Subscription s) {
                s.request(4);
            }

            @Override
            public void onNext(Integer integer) {
                observer.onNext(integer.toString());
            }

            @Override
            public void onError(Throwable t) {
                observer.onError(t);
            }

            @Override
            public void onComplete() {
                observer.onComplete();
            }
        });

        lift.subscribe(s -> Timber.d("s = %s", s));
複製程式碼

相關文章