私は一般的にRXJavaに比較的慣れていません(実際にはRXJava2でのみ使用を開始しました)。私が見つけることができるほとんどのドキュメントはRXJava1である傾向があります。私は通常、両方の間で翻訳できますが、Reactive全体が非常に大きいため、優れたドキュメントを備えた圧倒的なAPIです(見つけた場合)。私は自分のコードを合理化しようとしています。赤ちゃんのステップでそれをやりたいのです。私が解決したい最初の問題は、現在のプロジェクトでよく行うこの一般的なパターンです。
成功した場合、2番目のリクエストを行うために使用するリクエストがあります。
どちらかが失敗した場合は、どちらが失敗したかを識別できる必要があります。 (主にカスタムUIアラートを表示するため)。
これは私が今それを通常行う方法です:
(簡単にするために.subscribeOn/observeOn
を省略)
Single<FirstResponse> first = retrofitService.getSomething();
first
.subscribeWith(
new DisposableSingleObserver<FirstResponse>() {
@Override
public void onSuccess(final FirstResponse firstResponse) {
// If FirstResponse is OK…
Single<SecondResponse> second =
retrofitService
.getSecondResponse(firstResponse.id) //value from 1st
.subscribeWith(
new DisposableSingleObserver<SecondResponse>() {
@Override
public void onSuccess(final SecondResponse secondResponse) {
// we're done with both!
}
@Override
public void onError(final Throwable error) {
//2nd request Failed,
}
});
}
@Override
public void onError(final Throwable error) {
//firstRequest Failed,
}
});
RXJava2でこれに対処するためのより良い方法はありますか?
flatMap
とバリエーション、さらにはSingle.Zip
などを試しましたが、これに対処するための最も簡単で一般的なパターンが何であるかわかりません。
FirstRequestがSecondRequestで必要な実際のToken
をフェッチするのではないかと思っている場合に備えて。トークンなしで2回目のリクエストを行うことはできません。
フラットマップを使用することをお勧めします(オプションの場合は retrolambda )。また、何もしていない場合は、戻り値(Single<FirstResponse> first
など)を保持する必要はありません。
retrofitService.getSomething()
.flatMap(firstResponse -> retrofitService.getSecondResponse(firstResponse.id)
.subscribeWith(new DisposableSingleObserver<SecondResponse>() {
@Override
public void onSuccess(final SecondResponse secondResponse) {
// we're done with both!
}
@Override
public void onError(final Throwable error) {
// a request request Failed,
}
});
This の記事は、RxJavaの一般的な構造をスタイルで考えるのに役立ちました。可能であれば、チェーンを高レベルのアクションのリストにして、一連のアクション/変換として読み取ることができるようにします。
[〜#〜] edit [〜#〜]ラムダがなくても、flatMapにFunc1
を使用できます。同じことをもっと多くのボイラープレートコードで行います。
retrofitService.getSomething()
.flatMap(new Func1<FirstResponse, Observable<SecondResponse> {
public void Observable<SecondResponse> call(FirstResponse firstResponse) {
return retrofitService.getSecondResponse(firstResponse.id)
}
})
.subscribeWith(new DisposableSingleObserver<SecondResponse>() {
@Override
public void onSuccess(final SecondResponse secondResponse) {
// we're done with both!
}
@Override
public void onError(final Throwable error) {
// a request request Failed,
}
});
これはあなたのために働きませんか?
retrofitService
.getSomething()
.flatMap(firstResponse -> retrofitService.getSecondResponse(firstResponse.id))
.doOnNext(secondResponse -> {/* both requests succeeded */})
/* do more stuff with the response, or just subscribe */