让我们用Rx编写两种方法:
Maybe<Foo> getFooFromLocal
Single<Foo> getFooFromNetwork
当我们检查 Foo 的本地存储时,我想写一个链。如果我们没有 Foo ,我们应该从网络上获取它,然后将其保存到本地存储,然后再从本地存储中获取并将其传递给我们的订户。
storage
.getFooFromLocal()
.switchIfEmpty(network.getFooFromNetwork().map { it[0] }
.flatMapCompletable { storage.saveFoo(it) }
.andThen(storage.getFooFromLocal()))
.subscriber(/**/)
问题是andThen
部分在完成传递到flatMapCompletable
之前完成。我发现如果我将Maybe.defer{}
包裹起来,我可以摆脱这个问题。但根据andThen
的文件
它
返回一个
Maybe
,它将订阅此Completable。
也许已经
了表示延迟计算和发出可能的值或异常
所以问题是我的andThen
部分在完成完成之前运行的原因。写这种链的最佳和最优雅的方法是什么。
调用日志:
06:05:58.803 getFooFromLocal
06:05:58.804 getFooFromLocal
06:05:58.804 getFooFromNetwork
06:05:59.963 saveFoo
答案 0 :(得分:1)
这对我有用:
public class AndThenTest {
Integer value;
@Test
public void test() {
getFromLocal()
.switchIfEmpty(getFromNetwork()
.flatMapCompletable(v -> saveFoo(v))
.andThen(getFromLocal()))
.doOnSuccess(e -> System.out.println("Success: " + e))
.test()
.awaitDone(5, TimeUnit.SECONDS)
.assertResult(10);
}
Maybe<Integer> getFromLocal() {
return Maybe.fromCallable(() -> {
System.out.println("FromLocal called");
return value;
});
}
Single<Integer> getFromNetwork() {
return Single.fromCallable(() -> {
System.out.println("FromNetwork called");
return 10;
}).delay(100, TimeUnit.MILLISECONDS)
;
}
Completable saveFoo(Integer v) {
return Completable.fromRunnable(() -> {
System.out.println("SaveFoo called");
value = v;
});
}
}
并打印:
FromLocal called
FromNetwork called
SaveFoo called
FromLocal called
Success: 10
所以我的猜测是你没有展示的其中一种方法存在错误。