我对我的原始答案进行了一些重新评估,得出的结论是,根本不需要对网络响应/从网络获取数据的需要进行大多数就地检查。
首先,如果网络请求出错,将抛出一个异常,该异常将上升到链的上游,并由observable的onError订阅者处理。
其次,也不需要检查请求是否成功,因为通过使用异常,它只能在调用链中的下一步时成功。
第三,使用
takeWhile
使事情变得更加复杂,因为它实际上是需要的。
我决定使用一个简单的flatMap Lambda来解决这个问题,该Lambda在内部使用一个非常直接的if语句。因此,我认为代码更具可读性和可理解性。
下面您可以找到我的问题的最终解决方案:
package com.appenetic.fame.model.repository.remote;
import android.support.annotation.NonNull;
import com.annimon.stream.Optional;
import com.appenetic.fame.api.service.LocationService;
import com.appenetic.fame.api.service.LocationServiceQueryBuilder;
import com.appenetic.fame.model.LocationCollection;
import com.appenetic.fame.model.repository.local.LocalLocationCollectionRepository;
import org.joda.time.DateTime;
import org.joda.time.Interval;
import java.io.IOException;
import io.reactivex.Observable;
/**
* Created by shel on 18.01.18.
*/
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()
.flatMap(locationCollectionOptional -> {
if (shouldFetch(locationCollectionOptional)) {
return persistLocationCollection(fetchLocationCollection().blockingFirst());
}
return Observable.just(locationCollectionOptional.get());
});
}
//================================================================================
// Private methods
//================================================================================
private Observable<LocationCollection> fetchLocationCollection() throws IOException {
return Observable.fromCallable(() -> {
LocationServiceQueryBuilder queryBuilder = LocationServiceQueryBuilder.query();
return queryBuilder.invoke(locationService).execute().body();
});
}
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;
}
}
}