然后在可完成的

时间:2017-08-23 08:52:07

标签: android rx-java rx-kotlin

让我们用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

1 个答案:

答案 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

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