为什么 RxJava2 doOnSubscribe 运行 顺序混乱?

Why RxJava2 doOnSubscribe run with confused order?

以下代码打印 1、2

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

然后打印 2、1

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

在 RxJava1 中,这两个代码都打印“2, 1”,因为 doOnSubscribe 在下游订阅上游之前调用。

在 RxJava2 中,订阅是从上游到下游发生的(Observer.onSubscribe),但 doOnSubscribe 仍然在订阅之前调用。于是就出现了乱序。

连我也能给出更糊涂的情况:

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();

它按我的预期打印“3、4、1、2”,但不是大多数人的预期。

这是设计使然的行为吗?如果是,有什么好处?

subscribeOn 在指定线程上启动一个新的订阅链,但为了支持取消,它必须首先调用 onSubscribe 和一个可以提前取消的 Disposable -考虑在调用 onSubscribe 之前使正在进行昂贵准备的异步源超时。理论上,你也有可能在 3、4 和 1、2 之间得到各种交错。