• 使用 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>
    写在后面:

    1. 子曰:「学而不思则罔,思而不学则殆」。
    2. 站点地图
    2. 本作品作者为 Lshare,采用知识共享署名 4.0 国际许可协议进行许可。
  • 相关阅读:
    完整的开源和商业软件平台
    免费开源的文件比较/合并工具
    Javascript面向对象基础
    Javascript面向对象基础
    引入外部js获取dom为null的问题
    闭包函数
    初识对象
    构造函数
    内置对象
    Math对象
  • 原文地址:https://www.cnblogs.com/lshare/p/11333983.html
Copyright © 2020-2023  润新知