【发布时间】:2018-01-19 12:21:28
【问题描述】:
我是整个函数式编程和反应式概念的新手,并试图解决以下问题。
我有一个 API 客户端,我正在为其使用 Retrofit。 还有一个本地数据库充当 API 响应的持久缓存。
我想要实现的是这样的:
- 从本地数据库加载对象
- 如果没有对象或数据库返回空对象:
- 执行 API 请求并从在线来源获取数据
- 之后,持久化接收到的数据并返回持久化的数据
- 如果对象从本地数据库返回,请检查是否需要在线更新
- 需要在线更新(在线获取数据,持久化并返回持久化对象)
- 不需要在线更新(返回本地数据)
我想出的是以下内容:
public class LocationCollectionRepository {
private final static Integer fetchInterval = 30; //Minutes
private final LocationService locationService;
private final LocalLocationCollectionRepository localRepository;
public LocationCollectionRepository(@NonNull LocationService locationService, @NonNull LocalLocationCollectionRepository localRepository) {
this.locationService = locationService;
this.localRepository = localRepository;
}
public Observable<LocationCollection> getLocationCollection() throws IOException {
return localRepository.getLocationCollection()
.takeWhile(this::shouldFetch)
.flatMap(remoteCollection -> fetchLocationCollection())
.takeWhile(this::isRequestSuccessful)
.flatMap(locationCollectionResponse -> persistLocationCollection(locationCollectionResponse.body()));
}
//================================================================================
// Private methods
//================================================================================
private Observable<Response<LocationCollection>> fetchLocationCollection() throws IOException {
return Observable.fromCallable(() -> {
LocationServiceQueryBuilder queryBuilder = LocationServiceQueryBuilder.query();
return queryBuilder.invoke(locationService).execute();
});
}
private Observable<LocationCollection> persistLocationCollection(@NonNull LocationCollection locationCollection) {
return localRepository.saveLocationCollection(locationCollection);
}
private boolean shouldFetch(@NonNull Optional<LocationCollection> locationCollection) {
if (locationCollection.isPresent()) {
Interval interval = new Interval(new DateTime(locationCollection.get().getTimestamp()), new DateTime());
return locationCollection.get().getHashValue() == null || interval.toDuration().getStandardMinutes() > fetchInterval;
} else {
return true;
}
}
private boolean isRequestSuccessful(Response<LocationCollection> locationCollectionResponse) throws Exception {
if (locationCollectionResponse == null || !locationCollectionResponse.isSuccessful()) {
throw new Exception(locationCollectionResponse.message());
}
return true;
}
}
我遇到的问题是,如果数据库返回 null,我的订阅回调中不会返回任何对象。
我已经尝试过defaultIfEmpty-Method 但得出的结论是这也无济于事,因为它需要一个对象而不是可观察的。
任何想法,如何解决这个问题?
【问题讨论】:
标签: android caching functional-programming reactive-programming rx-java2