我有一个方法应该使用多个observable重新加载DB。毕竟它应该调用方法setupPlace(selecetedPlace),但只能调用一次。每个observable都返回不同的对象(void,object,listOfObjects)。
private void reloadDatabaseFromRest(final Place selectedPlace, final Event selectedEvent) throws ParseException {
Observable.concat(DatabaseManager.getInstance().clearDatabase(),
mPlaceUseCase.getPlacesListFromRestObservable()
.filter(places -> places != null && !places.isEmpty())
.doOnNext(places -> mPlaceUseCase.savePlacesToRepository(places)),
mPlaceUseCase.saveSelectedPlace(selectedPlace),
mEventUseCase.getEvenListObservableFromRest(selectedPlace.getId())
.doOnNext(eventList -> mEventUseCase.saveEventsToRepository(eventList)),
mEventUseCase.saveSelectedEventObservable(selectedEvent))
.takeLast(1)
.subscribe(o -> mSplashScreenUI.setupPlace(selectedPlace));
}
但是这个方法只在最后一个observable上做subsribe()而没有调用其他的(我是对的吗?)。我尝试使用过滤器,zip和制作愚蠢的if(o instanceOf ArrayList)子句,但这是错误的方法。请有人帮帮我吗?
答案 0 :(得分:4)
您可以使用Completable
类型。 Completable只是告知订阅者流已完成。
将您需要订阅的每个可观察事项包含在一个包含Completable.fromObservable()
的Completable中,然后将它们与Completable.merge()
合并(并行启动),或者将它们(一个接一个地连续)与Completable.concat
连接起来
注意: 确保您打包到Completable的所有可观察对象都会调用onComplete,因此不是无休止的流。
答案 1 :(得分:1)
非常感谢@koperko!它就像一个魅力,这正是我所需要的。 在重写方法期间,我注意到第一个Observable发出了6个项目(clearDatabase()),所以我将它包装到Completable中并且它可以工作! 我没有使用concat(),而是使用了flatMap():
private void reloadDatabaseFromRest(final Place selectedPlace, final Event selectedEvent) {
Completable.fromObservable(
DatabaseManager.getInstance().clearDatabase()
.flatMap(aVoidDB -> mPlaceUseCase.getPlacesListFromRestObservable().filter(places -> places != null && !places.isEmpty()))
.flatMap(places -> mPlaceUseCase.savePlacesToRepository(places))
.flatMap(aVoidPlace -> mPlaceUseCase.saveSelectedPlace(selectedPlace))
.flatMap(aVoidSelectedPlace -> {
try {
return mEventUseCase.getEvenListObservableFromRest(selectedPlace.getId());
} catch (ParseException e) {
Log.e(TAG, e.getMessage());
return null;
}
})
.filter(eventList -> eventList != null)
.flatMap(eventList -> mEventUseCase.saveEventsToRepository(eventList))
.flatMap(aVoidEvents -> mEventUseCase.saveSelectedEventObservable(selectedEvent)))
.subscribe(() -> {
mSplashScreenUI.setupPlace(selectedPlace);
});
}