RxJava 1 Completable.concat不等待完成的先前完成

时间:2018-02-19 03:50:00

标签: android rx-java

我在Android应用程序中使用RxJava 1(1.3.6)来控制应用程序启动流程。

应用程序在启动时所做的第一件事就是对某些配置值发出单个网络请求,然后初始化应用程序的2个不同部分(这两个部分都会产生网络请求)。为此,所有上述3个启动项都包含在返回Completable s的方法中。基本上,每种方法都是这样的:

private Completable initializeConfig(String configUrl) {
    return Completable.fromSingle(configProvider.requestConfigSingle(configUrl)
            .doOnSuccess(configResponse -> {
                // store the application configuration
                storeConfig(configResponse);
            }));
}

这只是配置方法,但其他两种方法看起来非常像这样:获取一些网络信息,输出数据等等,并且都返回Completable并且是异步的。

要控制启动流程,我尝试使用Completable.concat方法,如下所示:

@Override
public Completable startup(final String configUrl) {
    return Completable.concat(initializeConfig(configUrl), Completable.merge(initializeFirstPart(), initializeSecondPart()));
}

我看到的是initializeConfig方法被调用,在Completable完成之前,initializeFirstPartinitializeSecondPart方法都被调用。

我希望看到的是initializeConfig方法将被调用,当Completable完成时,initializeFirstPartinitializeSecondPart方法将被调用并且并行运行

我是否遗漏了某些内容或未了解Completable.concat方法的工作原理?

2 个答案:

答案 0 :(得分:1)

您的startup方法直接调用这些方法,因为没有魔法(语言特性)会自动推迟在括号内执行方法调用。换句话说,这就是你写的:

@Override
public Completable startup(final String configUrl) {
    Completable c1 = initializeConfig(configUrl);
    Completable c2 = initializeFirstPart();
    Completable c3 = initializeSecondPart();
    return Completable.concat(c1, Completable.merge(c2, c3));
}

你应该推迟执行c2和c3:

@Override
public Completable startup(final String configUrl) {
    Completable c1 = initializeConfig(configUrl);
    Completable c2 = Completable.defer(() -> initializeFirstPart())
                         .subscribeOn(Schedulers.computation());
    Completable c3 = Completable.defer(() -> initializeSecondPart())
                         .subscribeOn(Schedulers.computation());
    return Completable.concat(c1, Completable.merge(c2, c3));
}

答案 1 :(得分:0)

使用andThen代替concat,这将在第一个completable之后执行<{1}}

 @Override
    public Completable startup(final String configUrl) {
      Completable init = initializeConfig(configUrl);
      init.andThen(Completable.merge(initializeFirstPart(), 
      initializeSecondPart()).await());
    }