3

让我们采用 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 的 a。

也许已经

表示可能值或异常的延迟计算和发射

所以问题是为什么我的andThen部分在完成之前运行。编写这种链的最佳和优雅的方式是什么。

通话记录:

06:05:58.803 getFooFromLocal
06:05:58.804 getFooFromLocal
06:05:58.804 getFooFromNetwork
06:05:59.963 saveFoo
4

1 回答 1

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

所以我的猜测是你没有展示的一种方法有错误。

于 2017-08-23T13:29:19.137 回答