web-dev-qa-db-fra.com

Comment chaîner deux Completable dans RxJava2

J'ai deux Completable. J'aimerais faire le scénario suivant: Si le premier Completable arrive à onComplete, continuez avec le second Completable. Les résultats finaux seraient onComplete of second Completable.

Voici comment je le fais lorsque j'ai Single getUserIdAlreadySavedInDevice () et Completable login ():

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

}
36
Mladen Rakonjac

Vous recherchez l'opérateur andThen.

Retourne un Completable qui exécute d'abord ce Completable, puis l'autre complétable.

firstCompletable
    .andThen(secondCompletable)

En général, cet opérateur est un "remplaçant" pour un flatMap sur 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)
89

TL; DR: les autres réponses manquent une subtilité. Utilisez doThingA().andThen(doThingB()) si vous voulez l'équivalent de concat, utilisez doThingA().andThen(Completable.defer(() -> doThingB()) si vous voulez l'équivalent de flatMap.

Les réponses ci-dessus sont en quelque sorte correctes, mais je les ai trouvées trompeuses, car elles manquent d'une subtilité dans l'évaluation enthousiaste.

doThingA().andThen(doThingB()) appellera doThingB() immédiatement mais ne souscrira qu'à l'observable renvoyé par doThingB() lorsque l'observable renvoyé par doThingA() sera terminé.

doThingA().andThen(Completable.defer(() -> doThingB()) appellera doThingB() seulement après la fin de la tâche A.

Ceci est important uniquement si doThingB() a des effets secondaires avant un événement subscribe. Par exemple. Single.just(sideEffect(1)).toCompletable()

Une implémentation qui n'a pas d'effets secondaires avant l'événement subscribe (une véritable observable à froid) pourrait être Single.just(1).doOnSuccess(i -> sideEffect(i)).toCompletable().

Dans le cas où cela m'est simplement mordu, il existe une logique de validation et doThingB() lance immédiatement une mise à jour asynchrone de la base de données complétant un objet VertX ObservableFuture. C'est mauvais. On peut soutenir que doThingB() devrait être écrit pour mettre à jour la base de données uniquement lors de votre abonnement, et je vais essayer de concevoir les choses de cette manière à l'avenir.

50
Sparky

Essayer

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)

3
Deni Erdyneev