Как связать два Completable в RxJava2

У меня есть два Completable. Я хотел бы сделать следующий сценарий: Если первый Completable получает onComplete, продолжайте со вторым Completable. Окончательные результаты были бы onComplete второго Completable.

вот как я это делаю, когда у меня один getUserIdAlreadySavedInDevice () и Completable login ():

@Override
public Completable loginUserThatIsAlreadySavedInDevice(String password) {
    return getUserIdAlreadySavedInDevice()
            .flatMapCompletable(s -> login(password, s))

}

3 ответов


вы ищете andThen оператора.

возвращает Completable, который сначала запускает этот Completable, а затем другой completable.

firstCompletable
    .andThen(secondCompletable)

В общем, этот оператор является "замена" на flatMap on 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)

TL; DR: другие ответы пропускают тонкость. Использовать doThingA().andThen(doThingB()) Если вы хотите эквивалент concat используйте doThingA().andThen(Completable.defer(() -> doThingB()) Если вы хотите эквивалент flatMap.

приведенные выше ответы являются своего рода правильными, но я нашел их вводящими в заблуждение, потому что они упускают тонкость о нетерпеливой оценке.

doThingA().andThen(doThingB()) будем называть doThingB() немедленно, но только подписаться на observable возвращается 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() должен быть написан только для обновления базы данных после подписки, и я собираюсь попробовать и разработать вещи таким образом в будущем.


попробовать

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)