我是RxJava的新手,面临如下问题:
我有两个Completable对象来存储一些数据。我希望触发第一个,然后在第一个成功完成后启动第二个。应阻止对第二个Completable的调用,直到第一个完成成功。此外,如果第一个已完成错误,则还应跳过另一个。
查看文档和其他SO问题,似乎concatWith
或andThen
对我有用。但是在手动测试和单元测试中,我都可以看到第二个完成并行与第一个并行触发:/
首次完成
public Completable doA() {
Log.d(TAG, "class call");
return db.countRows()
.doOnSuccess(integer -> {
Log.d(TAG, "found rows: "+integer);
})
.doOnError(Throwable::printStackTrace)
.flatMapCompletable(this::customAction);
}
private Completable customAction(final int count) {
Log.d(TAG, "count: "+count);
if (count > 0) {
Log.d(TAG, "no rows, skip");
return Completable.complete();
}
final User user = ...
return db.save(user); // return Completable
}
第二次完成
public Completable doB() {
Log.d(TAG, "call to B");
// ...
}
在A
之后尝试调用B.public Completable someMethod() {
Log.d(TAG, "someMethod");
return doA()
.andThen(doB());
// this also doesn't work
//.concatWith(doB());
}
订阅
someMethod()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnComplete(() -> {
Log.d(TAG, "complete");
// ...
})
.doOnError(throwable -> {
Log.d("Main", "error "+throwable.getMessage());
// ...
})
.subscribe();
当我运行我的应用程序并检查日志时,我可以看到:
D/Some method: some method
D/DoA: class call
D/DoB: class call // <- why here?
D/DoA: found rows: 0
D/DoA: count: 0
以下单元测试也失败了:
@Test
public void test() {
when(doa.doA()).thenReturn(Completable.error(new Exception("test")));
observe(); // subscription with TestObserver
verify(dob, never()).doB(); // fails with NeverWantedButInvoked
}
我错过了什么?
答案 0 :(得分:2)
因为您致电doB()
。让我改写你的流程:
public Completable someMethod() {
Log.d(TAG, "someMethod");
// doA() inlined
LOG.d("class call");
Completable a = ...
// doB() inlined
Log.d("class call");
Completable b = ...
return a.andThen(b);
}
答案 1 :(得分:0)
您可以使用 andThen()或 concatWith()运算符。
返回一个Completable,该Completable首先运行此Completable,然后运行另一个Completable。
andThen()
firstCompletable
.andThen(secondCompletable)
通常,此运算符是Completable上flatMap的“替换”:
Completable andThen(CompletableSource next)
<T> Maybe<T> andThen(MaybeSource<T> next)
<T> Observable<T> andThen(ObservableSource<T> next)
<T> Flowable<T> andThen(Publisher<T> next)
<T> Single<T> andThen(SingleSource<T> next)
concatWith :
firstCompletable
.concatWith(secondCompletable)