【问题标题】:Rxjava - only call network if not already in progressRxjava - 如果尚未进行,则仅调用网络
【发布时间】:2018-06-29 19:59:26
【问题描述】:

我正在使用改造和 rxjava 创建一个存储库,如果之前没有检索到任何数据,它将调用网络,如果存在则从内存中返回缓存。

但是,如果您同时调用存储库,它会失败,它会多次调用网络。这是我目前的解决方案,存储库是一个单例并存储网络调用是否已经在进行中,如果是,则只返回可观察的内存。

IDatabaseInteractor databaseInteractor;
INetworkInteractor networkInteractor;
Data data;

boolean networkCallInProgress = false;

@Override
public Observable<Data> getData() {
    Observable<Data> memoryObservable = data.getObservable();
    Observable<Data> networkObservable;

    //Sure this could be done in a better way...
    if (!networkCallInProgress) {
        getBoostersInPnetworkCallInProgressrogress = true;
        networkObservable = networkInteractor.getBoosters().toObservable()
                .doFinally(() -> networkCallInProgress = false);
    } else {
        networkObservable = Observable.empty();
    }

    return Observable.merge(memoryObservable, networkObservable)
            .firstElement()
            .toObservable()
            .onErrorResumeNext((throwable) -> memoryObservable)
            .flatMap(boosterData -> memoryObservable);
}

这可行,但有没有更优雅的解决方案使用 rxjava 来了解网络 observable 是否已经被调用?

【问题讨论】:

    标签: java android rx-java retrofit2


    【解决方案1】:

    首先,您可以通过 Dagger 使用 Singleton 实现,它实际上只是保持到您的存储库类的一次性创建对象的链接。

    根据多次执行,您可以使用一个流(例如 rx 订阅甚至 android 的 LiveData)从您的存储库(例如在 ViewModel 中)获取数据到您的视图和其他以获取您的数据。

    1. 创建存储库后,您开始重复下载 从服务器获取数据并填充 LiveData 流的规则。
    2. 在 您的意见,您只需收听 LiveData 流。

    在这种情况下,您将只调用一次而无需任何检查,并从应附加到您的存储库的任何视图中获取数据。

    【讨论】:

      【解决方案2】:

      我通常是按以下方式做的:

      1.-云端和磁盘数据存储应该执行相同的操作,然后创建一个接口DataStore

      interface DataStore {
        private void Observable<SOmeData> getTheData();
      }
      

      2.- 创建您的缓存系统。

      3.- 创建CloudDataStoreDiskDataStore,两者都必须实现DataStore 接口。 DiskDataStore 应该包含缓存以及它使用缓存中定义的操作包装其操作

      4.- 创建DataStoreFactory 并同时注入(云和磁盘数据存储)。在这里,您可以创建如下方法:

      private DataStore createDataStoreForUserListForExample(boolean force) {
          if (force) //you want a network call because maybe is a refresh from a pull to refresh
              return cloudDataStore
          else {
              if (cache.usersListIsCached()) return diskDataStore
              else return cloudDataStore
          }
      }
      

      5.- 现在,创建您的存储库并在其中注入 DataStoreFactory。在这里你应该有一个类似的函数:

      public void Observable<SomeData> getTheList(boolean force) {
        DataStore ds = factory.createDataStoreForUserListForExample(force);
        return ds.getTheData();
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-03-03
        • 1970-01-01
        • 1970-01-01
        • 2018-10-28
        • 2021-07-30
        相关资源
        最近更新 更多