ReactiveX / RxJava

RxJava – Reactive Extensions for the JVM – a library for composing asynchronous and event-based programs using observable sequences for the Java VM.
Apache License 2.0
47.9k stars 7.6k forks source link

RxJava 2.2.2 startsWith subscribes the subsequence streams without subscribing to the upper stream #6214

Closed ykinuse closed 6 years ago

ykinuse commented 6 years ago

Hi, I'm not sure if this is a bug or an expected behavior. See an example below:

        PublishSubject<Integer> subject = PublishSubject.create();
        AtomicBoolean bool = new AtomicBoolean();
        subject
                .doOnSubscribe(s->{}) << not called
                .doOnNext(s->{}) << not called
                .startWith(0)
                .switchMap(o -> Observable
                        .empty()
                        .doOnSubscribe(s -> {
                            if (!bool.get()) {
                                subject.onNext(1); << called
                            }
                        }))
                .subscribe();

Scenario: In my use case, I subscribed to a source that chained with a #startWith operator. I performed a switchMap, expecting the next value terminates it and starts a new one. Subject emits something during the switchmap. Happens on both Observable/Flowable.

Expected: receive the new event Actual: receive nothing due to subject not subscribed yet.

Have not tested on other version.

Thanks

akarnokd commented 6 years ago

This is a valid behavior. The PublishSubject is not subscribed at that time because startWith hasn't finished yet switching to it. Consider using BehaviorSubject.create(0) instead and not doing that reentrant onNext call.

ykinuse commented 6 years ago

Thanks for the clarification. PublishSubject was used as an example of some source. So I'm assuming doOnSubscribe() chained after startWith does not guaranteed subscription established to the source? Was expecting a guaranteed subscription to source before startWith emits.

akarnokd commented 6 years ago

No. StartWith is like concat, subscribes the next source after the previous source has completed, thus no doOnSubscribe is called on the next source until that.

ykinuse commented 6 years ago

Cleared my doubts. Thanks for the swift & clear response!