RxJava2 使用可完成和 Then 运算符调用的序列顺序

RxJava2 order of sequence called with compleatable andThen operator

我正在尝试从 RxJava1 迁移到 RxJava2。我正在将之前 Observable<Void> 的所有代码部分替换为 Compleatable。但是我 运行 遇到了一个关于流调用顺序的问题。当我之前处理 Observables 并使用 maps 和 flatMaps 时,代码有效 'as expected'。但是 andthen() 运算符的工作方式似乎有点不同。这是简化问题本身的示例代码。

public Single<String> getString() {
    Log.d("Starting flow..")
    return getCompletable().andThen(getSingle());
}

public Completable getCompletable() {
    Log.d("calling getCompletable");
    return Completable.create(e -> {
                Log.d("doing actuall completable work");
                e.onComplete();
            }
    );
}

public Single<String> getSingle() {
    Log.d("calling getSingle");
    if(conditionBasedOnActualCompletableWork) {
        return getSingleA();
    }else{
        return getSingleB();
    }
}

最后我在日志中看到的是:

  1-> Log.d("Starting flow..")
  2-> Log.d("calling getCompletable");
  3-> Log.d("calling getSingle");
  4-> Log.d("doing actuall completable work");

你可能会发现我希望在第 3 行之前调用第 4 行(之后 andthen() 运算符的名称表明代码将被调用 'after' Completable 完成它的工作).以前我使用 Async.toAsync() 运算符创建 Observable<Void> 并且现在称为 getSingle 的方法在 flatMap 流中 - 它像我预期的那样工作,所以日志 4会出现在 3 之前。现在我尝试更改 Compleatable 的创建方式 - 就像使用 fromActionfromCallable 但它的行为相同。我也找不到任何其他运算符来替换 andthen()。强调 - 该方法必须是可完成的,因为它对 return 没有任何意义 - 它会更改应用程序首选项和其他设置(并且在全球范围内主要使用 'as expected')和稍后需要在流中进行这些更改。我还尝试包装 getSingle() 方法以某种方式创建一个 Single 并将 if 语句移动到 create 块中,但我不知道如何在其中使用 getSingleA/B() 方法。我需要使用它们,因为它们有自己的复杂性,复制代码没有意义。任何人都知道如何在 RxJava2 中修改它以使其表现相同?在继续使用流之前,有多个地方我依赖 Compleatable 作业来完成(比如刷新会话令牌、更新数据库、首选项等——在 RxJava1 中使用 flatMap 没问题)。

您可以使用延迟:

getCompletable().andThen(Single.defer(() -> getSingle()))

这样,您不会立即执行 getSingle() 的内容,而是仅当 Completable 完成并且 andThen 切换到 Single.