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 的创建方式 - 就像使用 fromAction
或 fromCallable
但它的行为相同。我也找不到任何其他运算符来替换 andthen()
。强调 - 该方法必须是可完成的,因为它对 return 没有任何意义 - 它会更改应用程序首选项和其他设置(并且在全球范围内主要使用 'as expected')和稍后需要在流中进行这些更改。我还尝试包装 getSingle()
方法以某种方式创建一个 Single 并将 if 语句移动到 create 块中,但我不知道如何在其中使用 getSingleA/B() 方法。我需要使用它们,因为它们有自己的复杂性,复制代码没有意义。任何人都知道如何在 RxJava2 中修改它以使其表现相同?在继续使用流之前,有多个地方我依赖 Compleatable 作业来完成(比如刷新会话令牌、更新数据库、首选项等——在 RxJava1 中使用 flatMap 没问题)。
您可以使用延迟:
getCompletable().andThen(Single.defer(() -> getSingle()))
这样,您不会立即执行 getSingle()
的内容,而是仅当 Completable
完成并且 andThen
切换到 Single
.
我正在尝试从 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 的创建方式 - 就像使用 fromAction
或 fromCallable
但它的行为相同。我也找不到任何其他运算符来替换 andthen()
。强调 - 该方法必须是可完成的,因为它对 return 没有任何意义 - 它会更改应用程序首选项和其他设置(并且在全球范围内主要使用 'as expected')和稍后需要在流中进行这些更改。我还尝试包装 getSingle()
方法以某种方式创建一个 Single 并将 if 语句移动到 create 块中,但我不知道如何在其中使用 getSingleA/B() 方法。我需要使用它们,因为它们有自己的复杂性,复制代码没有意义。任何人都知道如何在 RxJava2 中修改它以使其表现相同?在继续使用流之前,有多个地方我依赖 Compleatable 作业来完成(比如刷新会话令牌、更新数据库、首选项等——在 RxJava1 中使用 flatMap 没问题)。
您可以使用延迟:
getCompletable().andThen(Single.defer(() -> getSingle()))
这样,您不会立即执行 getSingle()
的内容,而是仅当 Completable
完成并且 andThen
切换到 Single
.