首页 > 解决方案 > RxJava Completable Concat

问题描述

考虑以下代码段:

@Test
public void completableConcatTest() {
    Completable.concat(completableTwoSeconds(), completableTwoSeconds())
            .doOnCompleted(() -> System.out.println("Both completed."))
            .await();
}

private Completable completableTwoSeconds() {
    PublishSubject<Void> subject = PublishSubject.create();

    CompletableFuture.supplyAsync(() -> {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        subject.onCompleted();
        return null;
    });

    return subject.doOnCompleted(() -> System.out.println("I'm completed." + Instant.now())).toCompletable();
}

运行时,测试产生以下输出:

I'm completed.2018-05-11T10:07:26.359Z
I'm completed.2018-05-11T10:07:26.380Z
Both completed.

显然,两个可完成程序并行运行,而不是按预期顺序运行。

你能解释一下我在这里做错了什么吗?

提前致谢!

标签: javarx-java

解决方案


CompletableFutures 几乎在声明后立即开始执行,这是您completableTwoSeconds()在 RxJava 之前执行的方式并concat参与其中。您必须至少推迟第二次调用才能completableTwoSeconds()让它在第一次完成后执行:

Completable.concat(
    completableTwoSeconds(), 
    Completable.defer(() -> completableTwoSeconds())
)
.doOnCompleted(() -> System.out.println("Both completed."))
.await();

推荐阅读