You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用RxJava+Retrofit优雅实现拉取List<A>后遍历请求对应List<B>合并返回

UI示例

需求说明

  • 第一步:通过参数tab1调用远端服务器API1查询Head列表
  • 第二步:遍历Head列表,针对每个Head通过API2查询对应的body列表,将Head与对应列表合并
  • 最终输出List<Wrapper<Head, List>>类型数据用于UI渲染

优化实现方案

这个场景属于典型的「嵌套请求+结果聚合」业务场景,通过RxJava操作符组合可以直接整合成单一流处理,不需要拆分两个独立请求逻辑,也不需要手动维护请求完成计数、中间LiveData中转:

// 单方法完成全流程请求,不需要拆分多步逻辑
public void queryFullListData(LifecycleOwner lifecycleOwner, MaterialZone mz, int pageNum) {
    VersaApiService.INSTANCE.getService(MaterialService.class)
            // 第一步:请求Header列表
            .queryMaterialCategory("9223372036854775807", mVerticalPageNum, VERTICAL_PAGE_SIZE)
            .compose(RxUtil.applyScheduler(lifecycleOwner))
            // 解析得到Header列表
            .map(pageResult -> pageResult.getResult().getRecords())
            // 将List<Header>拆分为单个Header逐个发射
            .flatMapIterable(headers -> headers)
            // 对每个Header异步请求对应的Body列表,同时保留Header引用用于合并
            .flatMap(header -> 
                VersaApiService.INSTANCE.getService(MaterialService.class)
                    .queryMaterial(header.getCategoryId(), mVerticalPageNum, VERTICAL_PAGE_SIZE)
                    .compose(RxUtil.applyScheduler(lifecycleOwner))
                    // 解析Body列表,和对应Header合并为Wrapper对象
                    .map(bodyPageResult -> {
                        List<Body> bodies = bodyPageResult.getResult().getRecords();
                        HeaderBodyWrapper wrapper = new HeaderBodyWrapper();
                        wrapper.setMaterialGroup(header);
                        wrapper.setMaterials(bodies);
                        return wrapper;
                    })
                    // 可选降级逻辑:单个Body请求失败时返回空内容Wrapper,不阻断整个流程
                    .onErrorReturnItem(new HeaderBodyWrapper(header, Collections.emptyList()))
            )
            // 所有请求完成后,将所有Wrapper聚合为最终列表
            .toList()
            .subscribe(wrappers -> {
                // 直接拿到最终结果更新UI
                mGroups.setValue(wrappers);
            }, throwable -> {
                // 统一异常处理
                VLog.d(HORIZONTAL_PAGE_SIZE + ", " + VERTICAL_PAGE_SIZE);
                VLog.d("onError: " + throwable.getMessage());
            });
}

方案优势

  • 逻辑简化:全流程在单个RxJava流中完成,不需要中间LiveData中转,也不需要手动判断所有请求是否完成,避免了原实现中单个请求失败就永远无法触发UI更新的问题
  • 效率更高:flatMap默认支持并发请求多个Body接口,比循环串行请求效率更高;如果需要最终列表顺序和Header列表顺序一致,可将flatMap替换为concatMapEager,在保持并发的同时保证输出顺序
  • 通用性强:这套操作符组合可以直接复用在所有「先查列表、再查每个子项关联数据、最后聚合结果」的同类业务场景中

内容的提问来源于stack exchange,提问作者Maximillian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 06:36:02