如何等待2个并行Retrofit请求全部完成后执行后续操作?
并行请求等待全部完成实现方案
你当前分开调用两个请求独立订阅的写法,没法统一监听两个请求的完成状态,直接用RxJava的Single.zip操作符就能实现并行发起请求、等所有请求成功返回后再执行后续逻辑的效果,不需要大幅改动你现有的UseCase封装,因为基类已经提供了single()方法可以拿到构建好的Single实例。
ViewModel层改造
把原来两个独立执行、单独赋值的请求逻辑合并,新增统一的加载方法:
var config: List<Configuration> = emptyList() var therapies: List<DtoTherapy> = emptyList() fun loadAllData( onAllSuccess: (config: List<Configuration>, therapies: List<DtoTherapy>) -> Unit, onAnyError: (error: ApiError) -> Unit ) { // 构建两个请求的Single实例,这里不要调用execute/ executeWithError,否则会提前独立订阅 val configSingle = getClientClientConfigUseCase.build(this).single() val therapySingle = getTherapiesUseCase.build(this).single() // zip会让两个Single在订阅后并行执行,等全部成功才会发送结果 Single.zip(configSingle, therapySingle) { configRes: ClientConfigResponse, therapyRes: List<DtoTherapy> -> Pair(configRes, therapyRes) } .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .doOnSubscribe { // 统一处理加载状态,比如显示全局loading onPrepareRequest(withLoader = true) } .doFinally { // 统一关闭加载状态 onFinishRequest(withLoader = true) } .subscribe( { (configRes, therapyRes) -> // 两个请求都成功才会走到这里,先赋值 config = configRes therapies = therapyRes // 回调通知页面所有数据加载完成 onAllSuccess(config, therapies) }, { throwable -> // 任意一个请求失败都会直接触发这里的错误回调 val error = mapError(throwable) // 可以把基类的mapError抽到公共工具类复用 onAnyError(error) } ).also { // 加入生命周期管理容器,避免内存泄漏 compositeDisposable.add(it) } }
注意:
Single.zip不会串行执行请求,两个接口会在订阅后同时发起,总耗时等于两个请求中耗时更长的那个,完全匹配你说的1s+4s请求总耗时4s的场景。
Fragment层调用调整
删掉原来分开调用两个请求的代码,换成调用统一的合并加载方法:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) setupUi(view) loadUserData() viewModel.loadAllData( onAllSuccess = { config, therapies -> // 这里就是两个接口全部成功返回的时机,直接写你的后续业务逻辑 // 比如渲染配置项、加载理疗列表数据等 }, onAnyError = { error -> // 处理请求失败逻辑,比如弹出错误提示、重试按钮等 } ) }
补充说明
- 原来单独调用
getClientProducts()、getTherapies()的方法可以保留,遇到只需要请求单个接口的场景正常用就行,不影响。 - 如果后续要加更多并行接口,直接在zip里追加对应的Single实例即可,zip原生支持最多9个实例的合并重载,超过9个可以传Single集合做合并。
- 不要在Fragment层直接拿UseCase做zip合并,请求逻辑统一收敛到ViewModel层,符合MVVM分层规范。
内容的提问来源于stack exchange,提问作者Mario Muresean
相关产品推荐
相关产品推荐

