web-dev-qa-db-ja.com

RXJava2:レトロフィットリクエストを連鎖させるための正しいパターン

私は一般的に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回目のリクエストを行うことはできません。

11

フラットマップを使用することをお勧めします(オプションの場合は 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, 
          }                        
   }); 
12
cyroxis

これはあなたのために働きませんか?

retrofitService
.getSomething()
.flatMap(firstResponse -> retrofitService.getSecondResponse(firstResponse.id))
.doOnNext(secondResponse -> {/* both requests succeeded */})
/* do more stuff with the response, or just subscribe */
3