使用 RxJava 進行嵌套串行網絡請求的一種方法


需求

有這樣一個列表數據,它包含了商店+訂單的信息,獲取訂單列表時,訂單實體中會包含商店的 ID,而列表顯示時需要商店的名稱和 logo,這時候就需要進行嵌套串行網絡請求了。

關鍵詞

flatMap緩存RetrofitRxJava

動手

(1)使用 Retrofit 定義網絡接口

// RemoteService.java
// 請求訂單信息
@POST("/order/v1/order_history")
Single<List<OrderResponse>> queryOrderList(@Body FetchOrderHistoryRequest request);
// 請求商店信息
@POST("/store/v1/store_query")
Single<StoreResponse> queryStore(@Body StoreQueryRequest request);

(2)使用 DataManager 管理數據

// DataManager.java
// 請求訂單信息
public Single<List<OrderResponse>> queryOrderList(String status) {
    FetchOrderHistoryRequest request = new FetchOrderHistoryRequest();
    request.setStatus(status);
    return mRemoteService.queryOrderList(request);
}

// 請求商店信息,並緩存 5min,如果不作緩存可能導致多次重復請求同一數據
public static final int DEFAULT_CACHE_TIME_MILLIS = 5 * 60 * 1000; // 5min

public Single<StoreResponse> queryStore(String storeId) {
    String storeKey = PrefConstant.getStoreKey(storeId);
    String storeJson = mMemberPref.getString(storeKey, null);
    Single<StoreResponse> storeSingle;
    if (!TextUtils.isEmpty(storeJson)) {
        storeSingle = Single.just(Json.fromJson(storeJson, StoreResponse.class));
    } else {
        StoreQueryRequest request = new StoreQueryRequest();
        request.setId(storeId);
        storeSingle = mRemoteService.queryStore(request)
            .doOnSuccess(storeResponse -> mMemberPref.put(storeKey,
                                                          Json.toJson(
                                                              storeResponse),
                                                          DEFAULT_CACHE_TIME_MILLIS));
    }
    return storeSingle;
}

注:

  1. mMemberPref 是我寫的一個使用 SharedPreferences 進行數據緩存的類,詳情查看 Pref.java

(3)多次FlatMap

dataManager.queryOrderList(status)
           .flatMapObservable((Function<List<OrderResponse>, ObservableSource<OrderResponse>>) Observable::fromIterable)
           .flatMap((Function<OrderResponse, ObservableSource<OrderHolder>>) orderResponse -> {
             OrderHolder orderHolder = new OrderHolder();
             orderHolder.setOrder(orderResponse);
             return dataManager.queryStore(orderResponse.getStoreId())
                               .flatMapObservable((Function<StoreResponse, ObservableSource<OrderHolder>>) storeResponse -> {
                                 orderHolder.setStore(storeResponse);
                                 return Observable.just(orderHolder);
                               });
           })
           .toList()
           .observeOn(AndroidSchedulers.mainThread())
           .subscribeOn(Schedulers.io())
           .subscribe(new SingleObserver<List<OrderHolder>>() {
             @Override
             public void onSubscribe(Disposable d) {
               disposable = d;
             }

             @Override
             public void onSuccess(List<OrderHolder> orderHolders) {
               if (orderHolders != null && !orderHolders.isEmpty()) {
                 getMvpView().showOrderList(orderHolders);
               } else {
                 getMvpView().showEmpty();
               }
             }

             @Override
             public void onError(Throwable e) {
               Timber.e(e);
               getMvpView().showError();
             }
           });
  }

說明:

  1. 第一次 flatMapObservable ,將 List<OrderResponse> 轉為 ObservableSource<OrderResponse>
  2. 第二次 flatMap,將 OrderResponse 轉為 ObservableSource<OrderHolder>
  3. 第三次 flatMapObservable ,將 StoreResponse 合並到 OrderHolder,再轉為ObservableSource<OrderHolder>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM