web-dev-qa-db-ja.com

Retrofit + RxJavaでのリクエストのチェーン化

2つのAPIを順番にリクエストし、それらのデータをSQLiteに保存します。

まず、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;
        });
    });

ラムダ関数を使用していなかった場合、これは通常のネストされた呼び出しと同じくらい見苦しくなります。これはそれを行うより良い方法ですか?

19
Sourabh

map演算子を使用することは、API呼び出しの結果を保存するようなことを行うための最良の方法だとは思いません。

私がやりたいのは、それらをdoOnNext演算子内で分離することです。あなたの例は次のようになります:

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

(必要なobserveOnsubscribeOnを必要に応じて自分で追加してください)

22
Bartek Lipinski

はい、この正確な目的にflatmapを使用できます。以下の例を参照してください(サービスAがObservable<FooA>を返し、サービスBがObservable<FooB>を返すと仮定します)

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

             }
        });
21
Much Overflow