Как связать два завершенных в RxJava2
У меня два Завершенных. Я хотел бы сделать следующий сценарий:
Если первый Заполненный получает onComplete, продолжайте второй Завершенный. Конечные результаты будут onComplete второго Completed.
Вот как я это делаю, когда у меня есть Single getUserIdAlreadySavedInDevice() и Completed login():
@Override
public Completable loginUserThatIsAlreadySavedInDevice(String password) {
return getUserIdAlreadySavedInDevice()
.flatMapCompletable(s -> login(password, s))
}
Ответы
Ответ 1
Вы ищете оператора andThen
.
Возвращает Завершающий, который сначала запускает этот Завершенный, а затем другой завершаемый.
firstCompletable
.andThen(secondCompletable)
В общем случае этот оператор является "заменой" для a flatMap
на Completable
:
Completable andThen(CompletableSource next)
<T> Maybe<T> andThen(MaybeSource<T> next)
<T> Observable<T> andThen(ObservableSource<T> next)
<T> Flowable<T> andThen(Publisher<T> next)
<T> Single<T> andThen(SingleSource<T> next)
Ответ 2
TL; DR: другие ответы пропускают тонкость. Используйте doThingA().andThen(doThingB())
, если вы хотите эквивалент concat
, используйте doThingA().andThen(Completable.defer(() -> doThingB())
, если вы хотите эквивалент flatMap
.
Приведенные выше ответы являются своего рода правильными, но я нашел их вводящими в заблуждение, потому что они упускают тонкость в отношении нетерпеливой оценки.
doThingA().andThen(doThingB())
немедленно вызовет doThingB()
, но подписывается только на наблюдаемую информацию, возвращаемую doThingB()
, когда завершается наблюдаемая, возвращаемая doThingA()
.
doThingA().andThen(Completable.defer(() -> doThingB())
позвонит doThingB()
только после того, как вещь А будет завершена.
Это важно только в том случае, если doThingB()
имеет побочные эффекты перед событием подписки. Например. Single.just(sideEffect(1)).toCompletable()
Реализация, у которой нет побочных эффектов перед событием подписки (наблюдаемая в холодном состоянии), может быть Single.just(1).doOnSuccess(i -> sideEffect(i)).toCompletable()
.
В случае, который только что укусил меня, A - это некоторая логика проверки, и doThingB()
немедленно запускает асинхронное обновление базы данных, которое завершает VertX ObservableFuture. Это плохо. Возможно doThingB()
должен быть написан, чтобы обновлять базу данных только после подписки, и я собираюсь попытаться спроектировать вещи таким образом в будущем.
Ответ 3
Попробуйте
Completable.concat
Returns a Completable which completes only when all sources complete, one after another.
http://reactivex.io/RxJava/javadoc/io/reactivex/Completable.html#concat(java.lang.Iterable)