RxJava网络请求和缓存

时间:2014-12-01 13:41:18

标签: android rx-java

我正在寻找一个我试图在RxJava的帮助下实现的流程示例。

假设我想显示数据列表。流程应如下所示:

  1. 读取缓存。如果它包含数据,请显示它;
  2. 向服务器发送API请求:

    如果它返回了数据,则将其缓存并显示。

    如果它返回并且错误并且没有缓存数据,则显示错误。

    如果它返回并且出现错误并且有缓存的内容,则不执行任何操作。

  3. 现在我有一个method that does something similar(来自Jake's u2020的很多灵感)。主要区别在于它使用内存缓存,这意味着不需要单独的Observable来从缓存中读取它,它可以同步完成。

    我不知道如何组合两个observable(一个用于从缓存读取而另一个用于API调用)并获得上述流程。

    有什么建议吗?

2 个答案:

答案 0 :(得分:2)

我想我解决了我的问题。可观察链看起来像这样:

apiCall()
        .map(data -> dataInMemory = data)
        .onErrorResumeNext(t -> data == null ?
                Observable.just(Data.empty()) : Observable.empty())
        .startWith(readDataFromCache().map(data -> dataInMemory = data))
        .subscribeOn(ioScheduler)
        .observeOn(uiScheduler)
        .subscribe(dataRequest);

重点是,如果readDataFromCache()引发错误,则会在不调用onCompleted()的情况下调用onError()。因此,它应该是您可以控制的自定义Observable

Data.empty()是我的数据的存根 - Subscriber应将其视为错误。

dataInMemory是我的控制器中的成员,充当内存缓存。


编辑:解决方案无法正常运行。一个用例的完成(见注释)没有实现。

编辑2:好吧,经过一些调整,解决方案 正常工作。修复程序返回不同类型的observable,具体取决于内存缓存的状态。有点脏。

答案 1 :(得分:1)

这是我的解决方案:

readDataFromCache().defaultIfEmpty(null)
        .flatMap(new Func1<Data, Observable<Data>>() {

            @Override
            public Observable<Data> call(final Data data) {
                if (data == null) {
                    // no cache, show the data from network or throw an error
                    return apiCall();
                } else {
                    return Observable.concat(
                            Observable.just(data),
                            // something cached, show the data from network or do nothing.
                            apiCall().onErrorResumeNext(Observable.<Data>empty()));
                }
            }
        });

我不添加subscribeOnobserveOn,因为我不确定readDataFromCache()应该使用ioScheduler还是uiScheduler