响应式编程之Single

194 阅读1分钟

以rxJava1为例分析。

public static void single(){
    Observable.just(1)
            .single()
            .subscribe(new Subscriber<Integer>() {
                @Override
                public void onCompleted() {

                }

                @Override
                public void onError(Throwable e) {

                }

                @Override
                public void onNext(Integer integer) {
                    System.out.println("this is onNext value = " + integer);
                }
            });
}

1、Single

public final Observable<T> single() {
    return lift(OperatorSingle.<T> instance());
}
public final <R> Observable<R> lift(final Operator<? extends R, ? super T> operator) {
    return unsafeCreate(new OnSubscribeLift<T, R>(onSubscribe, operator));
}

1.1、OperatorSingle

public final class OperatorSingle<T> implements Operator<T, T> {

    private final boolean hasDefaultValue;
    private final T defaultValue;

    public OperatorSingle(T defaultValue) {
        this(true, defaultValue);
    }

    private OperatorSingle(boolean hasDefaultValue, final T defaultValue) {
        this.hasDefaultValue = hasDefaultValue;
        this.defaultValue = defaultValue;
    }

    @Override
    public Subscriber<? super T> call(final Subscriber<? super T> child) {

        final ParentSubscriber<T> parent = new ParentSubscriber<T>(child, hasDefaultValue,
                defaultValue);
        child.add(parent);
        return parent;
    }

    static final class ParentSubscriber<T> extends Subscriber<T> {
        private final Subscriber<? super T> child;
        private final boolean hasDefaultValue;
        private final T defaultValue;

        private T value;
        private boolean isNonEmpty;
        private boolean hasTooManyElements;


        ParentSubscriber(Subscriber<? super T> child, boolean hasDefaultValue,
                T defaultValue) {
            this.child = child;
            this.hasDefaultValue = hasDefaultValue;
            this.defaultValue = defaultValue;
            request(2); // 调用#3
        }

        @Override
        public void onNext(T value) {
            if (!hasTooManyElements) {
                if (isNonEmpty) {
                    hasTooManyElements = true;
                    child.onError(new IllegalArgumentException("Sequence contains too many elements"));
                    unsubscribe();
                } else {
                    this.value = value;
                    isNonEmpty = true;
                }
            }
        }

        @Override
        public void onCompleted() {
            if (!hasTooManyElements) {
                if (isNonEmpty) {
                    child.setProducer(new SingleProducer<T>(child, value));
                } else {
                    if (hasDefaultValue) {
                        child.setProducer(new SingleProducer<T>(child, defaultValue));
                    } else {
                        child.onError(new NoSuchElementException("Sequence contains no elements"));
                    }
                }
            }
            // Otherwise we have already sent an onError message
        }

        @Override
        public void onError(Throwable e) {
            if (hasTooManyElements) {
                RxJavaHooks.onError(e);
                return;
            }

            child.onError(e);
        }

    }

}

1.2、OnSubscribeLift

public final class OnSubscribeLift<T, R> implements OnSubscribe<R> {

    public OnSubscribeLift(OnSubscribe<T> parent, Operator operator) {
        this.parent = parent;//ObservableJust
        this.operator = operator;//OperatorSingle
    }
}
public void call(Subscriber<? super R> o) {
    // OperatorSingle#call
    Subscriber<? super T> st = RxJavaHooks.onObservableLift(operator).call(o);
    st.onStart();
    parent.call(st);//JustOnSubscribe#call
}

2、Observable

static <T> Subscription subscribe(Subscriber<? super T> subscriber, Observable<T> observable) {

    if (!(subscriber instanceof SafeSubscriber)) {
        subscriber = new SafeSubscriber<T>(subscriber);
    }
    
    RxJavaHooks.onObservableStart(observable, 
                    observable.onSubscribe).call(subscriber);//OnSubscribeLift
    return RxJavaHooks.onObservableReturn(subscriber);
}

3、Subscriber

protected final void request(long n) {
    Producer producerToRequestFrom;
    synchronized (this) {
        if (producer != null) {
            producerToRequestFrom = producer;
        } else {
            addToRequested(n);
            return;
        }
    }
    // after releasing lock (we should not make requests holding a lock)
    producerToRequestFrom.request(n);
}

private void addToRequested(long n) {
    if (requested == NOT_SET) {
        requested = n;
    } else {
        final long total = requested + n;
        // check if overflow occurred
        if (total < 0) {
            requested = Long.MAX_VALUE;
        } else {
            requested = total;
        }
    }
}