【问题标题】:AndThen executes before completable finishedAndThen 在可完成之前执行
【发布时间】:2017-08-23 08:52:07
【问题描述】:

让我们用 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的文档 它

返回将订阅此 Completable 的 Maybe。

也许已经是

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

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

通话记录:

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

【问题讨论】:

  • 您的storage.getFooFromLocal() 可能是通过Maybe.just(cachedValue) 实现的,该Maybe.just(cachedValue) 在任何RxJava 活动开始之前执行。
  • GetFooFromLocal 通过Maybe.create 实现这里是可能创建的代码Maybe.create { s -&gt; if (this != null) s.onSuccess(this); s.onComplete() }
  • storage.getFooFromLocal() 在你的代码库中出现了两次,为什么你认为andThen 有责任?
  • getFooFromLocal 都在 getFooFromNetwork() 完成之前触发。我添加了一个日志来提问。

标签: android rx-java rx-kotlin


【解决方案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

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

【讨论】:

    猜你喜欢
    • 2016-10-07
    • 2019-02-22
    • 1970-01-01
    • 2021-07-23
    • 1970-01-01
    • 1970-01-01
    • 2016-09-12
    • 2017-06-07
    • 1970-01-01
    相关资源
    最近更新 更多