Dean Xu
Dean Xu

Reputation: 4691

Why RxJava2 doOnSubscribe run with confused order?

Following code print 1, 2

Observable.just(1)
    .doOnSubscribe(d -> System.out.println(1))
    .doOnSubscribe(d -> System.out.println(2))
    .blockingSubscribe();

And this print 2, 1

Observable.just(1)
    .doOnSubscribe(d -> System.out.println(1))
    .subscribeOn(Schedulers.newThread())
    .doOnSubscribe(d -> System.out.println(2))
    .blockingSubscribe();

In RxJava1, the two code both print "2, 1", because doOnSubscribe invoked before downstream subscribe to upstream.

In RxJava2, subscription happens from upstream to downstream (Observer.onSubscribe), but doOnSubscribe still invoked before subscription. So the confused order occured.

Even I can give a more confused situation:

Observable.just(1)
    .doOnSubscribe(d -> System.out.println(1))
    .doOnSubscribe(d -> System.out.println(2))
    .subscribeOn(Schedulers.newThread())
    .doOnSubscribe(d -> System.out.println(3))
    .doOnSubscribe(d -> System.out.println(4))
    .blockingSubscribe();

It print "3, 4, 1, 2" as my expected but not the most's expected.

Is this behavior by design? If yes, what's the benefit?

Upvotes: 2

Views: 4026

Answers (1)

akarnokd
akarnokd

Reputation: 70007

subscribeOn starts a new subscribe chain on the specified thread but in order to support cancellation, it has to first call onSubscribe with a Disposable that can be cancelled early on - think about timing out an async source that is doing expensive preparation before it calls onSubscribe. In theory, it is also possible you get all sorts of interleaving between 3, 4 and 1, 2.

Upvotes: 5

Related Questions