Tengo dos Completables. Me gustaría hacer el siguiente escenario: si el primer Completable llega a onComplete, continúe con el segundo Completable. Los resultados finales serían el Completado del segundo Completable.
Así es como lo hago cuando tengo Single getUserIdAlreadySavedInDevice() y Completable login() :
@Override public Completable loginUserThatIsAlreadySavedInDevice(String password) { return getUserIdAlreadySavedInDevice() .flatMapCompletable(s -> login(password, s)) }Está buscando el operador andThen .
Devuelve un Completable que primero ejecuta este Completable y luego el otro Completable.
firstCompletable .andThen(secondCompletable) En general, este operador es un "reemplazo" de flatMap en 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: las otras respuestas pierden una sutileza. Usa doThingA().andThen(doThingB()) si quieres el equivalente de concat , usa doThingA().andThen(Completable.defer(() -> doThingB()) si quieres el equivalente de flatMap .
flatMap() es la versión de mapeo de merge()concatMap() es la versión de mapeo de concat()Completable , necesita defer() para hacer que las llamadas a funciones sean perezosas como en las funciones de mapeo para Single u Observable (o preferiblemente para que no suceda nada hasta que presione suscribirse; esta es una buena convención a seguir y se usa en el Rx oficial bibliotecas, así como cualquier extensión Rx que haya encontrado, para usuarios avanzados esto se refiere solo a completables en frío, pero la mayoría de las personas pueden ignorarlo).concat(a, b) y a.andThen(b) es la sintaxisAlgunos ejemplos:
foo(a).andThen(bar(b)) hará lo siguiente:
foo(a)bar(b) incluso si el completable devuelto por el paso 1 devuelve un error1bar(b) solo si el último paso se completó con éxito foo(a).andThen(Completable.defer(() -> bar(b)) hará lo siguiente:
foo(a)1foo(a) tiene éxito, entonces llama a bar(b) Voy a omitir el tratamiento de merge() ya que se vuelve un poco más complicado, pero para resumir, ese es el que debes llamar si quieres "paralelismo".
Las respuestas anteriores son correctas, pero las encontré engañosas porque pierden una sutileza sobre la evaluación ansiosa.
doThingA().andThen(doThingB()) llamará a doThingB() inmediatamente, pero solo se suscribirá al observable devuelto por doThingB() cuando se complete el observable devuelto por doThingA() .
doThingA().andThen(Completable.defer(() -> doThingB()) llamará a doThingB() solo después de que la cosa A se haya completado.
Esto es importante solo si doThingB() tiene efectos secundarios antes de un evento de suscripción. Por ejemplo Single.just(sideEffect(1)).toCompletable()
Una implementación que no tiene efectos secundarios antes del evento de suscripción (un verdadero observable en frío) podría ser Single.just(1).doOnSuccess(i -> sideEffect(i)).toCompletable() .
En el caso de que me haya mordido, la cosa A es una lógica de validación y doThingB() inicia una actualización asíncrona de la base de datos inmediatamente que completa un VertX ObservableFuture. Esto es malo. Podría decirse que doThingB() debe escribirse solo para actualizar la base de datos al suscribirse, y voy a intentar diseñar cosas de esa manera en el futuro.
Probar
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)