当前,我在存储库类中有一个方法,该方法可从本地缓存和远程API提取数据。
public Observable<List<Items>> getItemsForUser(String userId {
return Observable.concatArrayEager(
getUserItemsLocal(userId), // returns Observable<List<Items>>
getUserItemsRemote(userId) // returns Observable<List<Items>>
);
}
当前,该方法首先获取本地数据(可能已过时)并返回它,然后使用来自远程API的新数据对其进行更新。
我想将实现更改为使用Observable.merge
,以便如果远程API请求首先完成,则首先显示该数据。但是,如果我只使用Observable.merge
,则会担心本地数据库请求可能会返回陈旧的数据,然后该数据将覆盖远程的新数据。
基本上,我想要类似的东西:
public Observable<List<ShoutContent>> getItemsForUser(String userId, ErrorCallback errorCallback) {
return Observable.merge(
getUserItemsRemote(userId),
getUserItemsLocal(userId)
.useOnlyIfFirstResponse()
}
因此,如果远程API请求首先完成,则该响应是唯一返回的响应。但是,如果本地请求首先完成,则我想返回该请求,然后在完成后返回远程请求。 RxJava是否有内置的类似内容?
编辑:我想补充一点,getUserItemsRemote
确实在Observable发出时更新了本地数据库,但是我认为我无法确保在本地请求完成之前将数据库更新,这使得本地请求将以陈旧数据响应的可能性。
答案 0 :(得分:0)
您可以使用takeUntil
运算符。
takeUntil
返回一个Observable,它发出由源Observable发出的项目,直到第二个ObservableSource发出一个项目为止。
在您的情况下,一旦发出远程Observable,您就必须停止观察本地可观察对象。该代码如下所示。
public Observable<String> getUserItemsLocal() {
return Observable.just("Local db response")
.delay(5, TimeUnit.SECONDS); // assume local db takes 5 seconds to emit
}
public Observable<String> getUserItemsRemote() {
return Observable.just("Remote Data")
.delay(1, TimeUnit.SECONDS); // remote data comes quicker, in 1 second
}
您的存储库代码类似
Observable<String> remoteResponse = getUserItemsRemote();
getUserItemsLocal().takeUntil(remoteResponse)
.mergeWith(remoteResponse)
.subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.d(TAG, "result: " + s);
}
});