完成后,RxJava将多个observable组合起来

时间:2017-01-19 14:21:57

标签: rx-java rx-android

我有一个方法应该使用多个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)子句,但这是错误的方法。请有人帮帮我吗?

2 个答案:

答案 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);
            });
}