2016-04-22 5 views
13

私は2つのAPIを順番にリクエストし、そのデータをSQLiteに保存したいと思います。Retrofit + RxJavaでリクエストをチェイン化

まず私はAPI Aへの要求を作成し、SQLテーブルaにデータを格納します。 API Bに依頼し、テーブルbにデータを、テーブルa_bにデータを格納します。 a_bに格納されたデータは、リクエストBからのものです。

RxJavaを使用してこれを行うにはどうすればよいですか。私は、ラムダ関数を使用していなかった場合は、このためにflatMapを使用することについて、どこかこの

apiService.A() 
    // store in DB here? How? maybe use map()? 
    .flatMap(modelA -> { 
     // or maybe store modelA in DB here? 
     return apiService.B().map(modelB -> { 
      storeInDB()l // store B here ? 
      return modelB; 
     }); 
    }); 

のようなものを読んで、これは通常のネストされた呼び出しのように醜いになります。これはもっと良い方法ですか?

答えて

13

私はmap演算子を使用すると、API呼び出しの結果を格納するようなもので行くための最善の方法だとは思わない(あなたのサービスを想定すると、AはObservable<FooA>返し、サービスBはObservable<FooB>を返します)。私がやりたい何

doOnNext事業者の内部でそれらのものを分離することです。私はそれがメインスレッド上で実行されますonNextでDBにデータを保存するためのコードを記述する場合

apiService.A() 
     .doOnNext(modelA -> db.store(modelA)) 
     .flatMap(modelA -> apiService.B()) 
     .doOnNext(modelB -> db.store(modelB)); 

+0

私はRxの 'do'演算子について知らなかった。 docsを読んだ後、doOnCompleteはこれに対してより良い機能ではないのですか? – Sourabh

+0

@Sourabhそれはあなたの 'Observable'に依存します。 apiからの呼び出しが成功した後に 'onComplete'が呼び出された場合は、yesになります。あなたの 'Observable'が複数のイベントを出すことができるなら、' doOnNext'のために行くべきです。あなたのケースでは 'doOnNext'と' doOnComplete'を使った 'Retrofit'は同じ結果になりますが、実際には' doOnComplete'はちょっと直感的です(純粋な習慣から 'doOnNext'を使いました)。私は意味 –

+0

、 'doOnComplete'を使用してdoOnComplete'代わりに、(B 'として' flatMap' – Sourabh

18

はい、この正確な目的のためにフラットマップを使用できます。以下の例を参照してください

api.serviceA() 
     .flatMap(new Func1<FooA, Observable<FooB>>() { 
      @Override 
      public Observable<FooB> call(FooA fooA) { 
       // code to save data from service A to db 

       // call service B 
       return api.serviceB(); 
      } 
     }) 
     .subscribeOn(Schedulers.io()) 
     .observeOn(AndroidSchedulers.mainThread()) 
     .subscribe(new Subscriber<FooB>() { 
      @Override 
      public void onCompleted() { 
      } 

      @Override 
      public void onError(Throwable e) { 

      } 

      @Override 
      public void onNext(FooB fooB) { 
       // code to save data from service B to db 

      } 
     }); 
+0

を(あなたがそれらを必要とまったく同じ、observeOnsubscribeOn自分に必要な追加):だからあなたの例では、このようなものになるだろう右?どのようにバックグラウンドスレッドの代わりにdbにデータを保存するには? –

+0

は別の 'flatMap'演算子を投げます。 flatMap((FooB) - > {//サービスBからデータを保存し、成功/失敗を示す観測可能性を返す})。subscribeOn() (Schedulers.io())。observeOn(AndroidSchedulers.mainThread())。doOnNext((isSuccess) - > {//これはメインスレッドでのみ実行されます}) ' –

+0

RxJava2ではどうしますか? – Ryan

関連する問題