为什么Completable和Observable之间的预订时间副作用安排不同?

时间:2018-08-20 16:09:38

标签: java rx-java reactive

我当前正在使用Rx 1。

我有以下测试案例:

static void printThread(String format, Object... objects) {
    System.out.println(String.format("%s %s", Thread.currentThread().getName(),
            String.format(format, objects)));
}

public void testFoo() throws InterruptedException {
    Observable.fromCallable(() -> { printThread("callable"); return 1L;})
              .subscribeOn(Schedulers.newThread())
              .doOnSubscribe(() -> printThread("A"))
              .doOnSubscribe(() -> printThread("B"))
              .subscribeOn(Schedulers.newThread())
              .doOnSubscribe(() -> printThread("C"))
              .subscribeOn(Schedulers.newThread())
              .doOnSubscribe(() -> printThread("D"))
              .toBlocking()
              .subscribe();

    printThread("next!");

    Completable.fromCallable(() -> { printThread("callable"); Thread.sleep(10_000); return 1L;})
              .subscribeOn(Schedulers.newThread())
              .doOnSubscribe(a -> printThread("A"))
              .doOnSubscribe(a -> printThread("B"))
              .subscribeOn(Schedulers.newThread())
              .doOnSubscribe(a -> printThread("C"))
              .subscribeOn(Schedulers.newThread())
              .doOnSubscribe(a -> printThread("D"))
               .andThen(Completable.fromAction(() -> printThread("E")))
               .andThen(Completable.fromAction(() -> printThread("F")).subscribeOn(Schedulers.newThread()))
               .await();
}

哪个会产生以下输出:

main D
RxNewThreadScheduler-1 C
RxNewThreadScheduler-2 B
RxNewThreadScheduler-2 A
RxNewThreadScheduler-3 callable
main next!
RxNewThreadScheduler-6 A
RxNewThreadScheduler-6 B
RxNewThreadScheduler-6 C
RxNewThreadScheduler-6 D
RxNewThreadScheduler-6 callable
RxNewThreadScheduler-6 E
RxNewThreadScheduler-7 F

Process finished with exit code 0

为什么ObservableCompletable之间的订阅时间副作用调度方式在行为上有区别?

我认为正在发生的事情是,在可观察到的情况下产生了该行为,因为预订发生在默认的单线程调度模式下,除了调用subscribeOn()之外,这就是为什么A和B发生在同一线程上,但其他所有原因发生在不同的线程上。

但是我不明白为什么这种行为会被更改为Completable。

1 个答案:

答案 0 :(得分:1)

RxJava 1在这方面有点不一致。 1.x Completable.subscribeOn在订阅时线程切换后调用onSubscribe,而对于ObservabledoOnSubscribe在线程切换到上游之前被调用。

使用RxJava 2,它们现在保持一致:

main D
RxNewThreadScheduler-1 C
RxNewThreadScheduler-2 A
RxNewThreadScheduler-2 B
RxNewThreadScheduler-3 callable
main next!
main D
RxNewThreadScheduler-4 C
RxNewThreadScheduler-5 A
RxNewThreadScheduler-5 B
RxNewThreadScheduler-6 callable