前言: 我们在一个页面中往往要并发请求多个接口获取数据, 并且更新UI, 暴力解决方法就是在一个方法中同步调用多次请求,我们可以使用rxjava的merge操作符解决问题.(ps: 以下示例代码使用kotlin实现)
1 merge 操作符
可以合并多个observable的输出, 但是数据可能会交叉发射的, 如下图所示:
image.png
所以如果需要按照顺序执行的请求, 可以换为使用contact操作符
使用merge标签的缺点:
当操作流中有一个Observable出现error, 则会阻断之后未执行的所有操作, 因此当我们希望每个操作流能够独立执行不收别的结果影响时, 可以使用mergeDelayError操作符
2. mergeDelayError
在功能上和merge一样,对于数据流的错误进行了处理, 当有数据流产生错误时错误通知会被保留, 直到所有的数据流都发射完毕才会走onError
image.png
当然 我们按照正常的error流程处理的话, 最后代码会回调到onError.
但是此时, 由于上游是多个observable, 我们可能会需要对不同的observable的错误进行不同处理,
解决措施: 我们可以在原始observable后面加上doOnError对其错误进行单独处理
上代码:
//上游有三个接口并发异步进行请求
val homeObservable = mApiService.getNewHomePage(map) //首页大接口
val recommendObservable = mApiService.getRecommendCar(hashMapOf("page" to "0")) //首页推荐车型
val financeConfigObservable = mApiService.getScf(hashMapOf()) //资金状态
//使用mergeDelayError操作符整合多个observable
Observable.mergeDelayError(
//因为首页大接口这里的数据会对界面的网络状态进行控制, 所以需要单独处理,另外两个接口即使是产生错误, 也不需要UI上进行变化,所以我这里没有进行处理
homeObservable.doOnError { if (showLoading) mView.showError(it) else mView.showDialogError(it) },
recommendObservable,
financeConfigObservable)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.compose(mView.syncLifecycle(FragmentEvent.DESTROY))
.subscribe({
when (it) {
is NewHomeBean -> {
bean = it
updateData(it.lawCar, true)
presaleBeanList = it.preSale
bidderBeanList = it.bidder
success(it)
}
is RecommendBean -> {
recommendBean = it
recommendSuccess(it)
}
is ScfBean -> scfBean = it
}
},{ // 这里的error可以处理另外两个流的error
},{})