RxJava 2入门:串行执行任务。 `andThen`或`defer`?

时间:2017-10-17 21:50:47

标签: rx-java2

我想在RxJava中连续运行两个步骤。我希望在第2步开始之前完成第1步:

step 1: start
step 1: finish
step 2: start
step 2: finish

我正在尝试不同的API变体,而RxJava正在并行运行我的两个步骤,这不是我想要的行为:

step 1: start
step 2: start
step 2: finish
step 1: finish

在下面的代码示例中,我尝试了andThendefer,并获得并行执行。如何解决这个问题,以便在成功完成另一步后执行一步?

方法名称andThen意味着顺序串行执行。方法defer采用一个函数生成另一个Completable,这是我期望的串行任务执行所需的方法签名。也没有给我我想要的结果。

我是否需要转换为Observable / Flowable?或者我可以用Completable链接两个步骤吗?

public class RxStep1Then2 {
    public static Completable simulateCompletable(ScheduledExecutorService es, String msg, int msDelay) {
        System.out.println(String.format("%s: start", msg));

        ScheduledFuture<?> future = es.schedule(() -> {
            System.out.println(String.format("%s: finish", msg));
        }, msDelay, TimeUnit.MILLISECONDS);

        return Completable.fromFuture(future);
    }

    public static void rxMain(ScheduledExecutorService es) {
//        Completable c = simulateCompletable(es, "step 1", 1000)
//                .andThen(simulateCompletable(es, "step 2", 500));

        Completable c = simulateCompletable(es, "step 1", 1000)
                .defer(() -> simulateCompletable(es, "step 2", 500));

        c.blockingAwait();
        System.out.println("blockingAwait done");
    }

    public static void main(String[] args) throws Exception {
        ScheduledExecutorService es = Executors.newScheduledThreadPool(5);
        System.out.println("Started ExecutorService.");

        rxMain(es);

        es.shutdown();
        es.awaitTermination(5, TimeUnit.MINUTES);
        System.out.println("Shutdown ExecutorService. Done.");
    }
}

1 个答案:

答案 0 :(得分:0)

并行执行是因为simulateCompletableCompletable创建之前启动了任务。您可以直接使用延迟Completable

Completable.fromAction(() -> System.out.println("First"))
    .delay(1, TimeUnit.SECONDS)
    .andThen(Completable.fromAction(() -> System.out.println("Second")))
    .blockingAwait();

请注意

Completable c = simulateCompletable(es, "step 1", 1000)
            .defer(() -> simulateCompletable(es, "step 2", 500));

不会链接任何操作,因为defer是一个创建独立Completable的静态工厂方法;第一个simulateCompletable&#39; s Completable就丢失了。