问题
Let's take two methods written with Rx:
Maybe<Foo> getFooFromLocal
Single<Foo> getFooFromNetwork
I want to write a chain when we check our local storage for Foo. If we don't have any Foo we should get it from the network then save it to the local storage and again get it from local storage and pass it to our subscriber.
storage
.getFooFromLocal()
.switchIfEmpty(network.getFooFromNetwork().map { it[0] }
.flatMapCompletable { storage.saveFoo(it) }
.andThen(storage.getFooFromLocal()))
.subscriber(/**/)
The problem is that andThen
part completes before completable passed into flatMapCompletable
. I found out that I can get rid of this problem if I wrap into Maybe.defer{}
. But according to the documentation of andThen
it
Returns a
Maybe
which will subscribe to this Completable.
And maybe is already
Represents a deferred computation and emission of a maybe value or exception
So the question is why my andThen
part run before completable finished. And what is the best and elegant way to write such chains.
Calls log :
06:05:58.803 getFooFromLocal
06:05:58.804 getFooFromLocal
06:05:58.804 getFooFromNetwork
06:05:59.963 saveFoo
回答1:
This works for me:
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;
});
}
}
and prints:
FromLocal called
FromNetwork called
SaveFoo called
FromLocal called
Success: 10
So my guess is that there is a mistake in one of the methods you are not showing.
来源:https://stackoverflow.com/questions/45834989/andthen-executes-before-completable-finished