web-dev-qa-db-ja.com

RxJava2で2つのCompletableをチェーンする方法

Completableが2つあります。次のシナリオを実行します。最初のCompletableがonCompleteに到達した場合、2番目のCompletableに進みます。最終結果は、2番目のCompletableのonCompleteになります。

これは、単一のgetUserIdAlreadySavedInDevice()およびCompletable login()がある場合の方法です。

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

}
36
Mladen Rakonjac

andThen演算子を探しています。

最初にこのCompletableを実行し、次に他のCompletableを実行するCompletableを返します。

firstCompletable
    .andThen(secondCompletable)

一般に、この演算子はflatMapCompletableの「置換」です。

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:他の答えは微妙な見落としがあります。 concatと同等のものが必要な場合はdoThingA().andThen(doThingB())を使用し、flatMapと同等のものが必要な場合はdoThingA().andThen(Completable.defer(() -> doThingB())を使用します。

上記の答えは一種の正しいものですが、彼らは熱心な評価についての微妙な点を見落としているため、誤解を招くものであることがわかりました。

doThingA().andThen(doThingB())は、すぐにdoThingB()を呼び出しますが、doThingB()によって返されるオブザーバブルが完了すると、doThingA()によって返されるオブザーバブルにサブスクライブします。

doThingA().andThen(Completable.defer(() -> doThingB())は、Aが完了した後にのみdoThingB()を呼び出します。

これは、doThingB()にサブスクライブイベントの前に副作用がある場合にのみ重要です。例えば。 Single.just(sideEffect(1)).toCompletable()

サブスクライブイベント(実際のコールドオブザーバブル)の前に副作用のない実装は、Single.just(1).doOnSuccess(i -> sideEffect(i)).toCompletable()です。

噛まれただけの場合、Aは何らかの検証ロジックであり、doThingB()は、VertX ObservableFutureを完了する非同期データベース更新をすぐに開始します。これは悪いです。おそらく、doThingB()は、サブスクライブ時にのみデータベースを更新するように作成する必要があり、将来的にはそのように設計してみます。

50
Sparky

試して

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