需求:原有一个订单列表页面,新增一种售后服务,但是能否申请这种售后服务有一些限制条件,这些限制条件呢原订单列表接口是不支持的,需要另外一个接口来补全这些状态信息。
实现代码:
//分页请求订单列表接口
Observable<List<OrderInfo>> observable = mOrderModel.getHavePaidList(pageIndex, mPageSize)
//1、补充状态数据再返回订单列表
.flatMap(new Function<CommonList<OrderInfo>, ObservableSource<List<OrderInfo>>>() {
@Override
public ObservableSource<List<OrderInfo>> apply(CommonList<OrderInfo> response) throws Exception {
if (response != null && ListUtils.isNotEmpty(response.data)) {
List<OrderInfo> list = response.data;
//封装参数
List<String> listOrderNo = new ArrayList<>();
for (OrderInfo orderInfo : list) {
listOrderNo.add(orderInfo.orderNo);
}
return mOrderModel.checkOrderStatus(listOrderNo)
//3、接口错误时不抛出异常,不能影响订单列表的展示
.onErrorResumeNext(observer -> {
//返回一个空的结果
observer.onNext(new MicroResponse<>());
//正常结束当前的Observable
observer.onComplete();
})
//2、请求订单状态数据,并完成拼装数据
.map(new Function<MicroResponse<List<StatusBean>>, List<OrderInfo>>() {
@Override
public List<OrderInfo> apply(MicroResponse<List<StatusBean>> checkResponse) throws Exception {
if (checkResponse != null && ListUtils.isNotEmpty(checkResponse.data)) {
//根据订单号,拼装状态数据
for (OrderInfo orderInfo : list) {
for (StatusBean statusBean : checkResponse.data) {
if (orderInfo.orderNo.equals(statusBean.orderNo)) {
orderInfo.status = statusBean.status;
break;
}
}
}
}
//补充过数据后的订单列表
return list;
}
});
} else {
return Observable.just(new ArrayList<>());
}
}
});
observable.safeSubscribe(new SimpleSubscriber<List<OrderInfo>>() {
@Override
public void onNext(List<OrderInfo> reponse) {
//加载数据等逻辑...
}
});
解析:
1、补充状态数据再返回订单列表
使用FlatMap 操作符对订单列表接口进行加工,并且返回可被订阅的Observable。
因为获取状态的接口参数需要从订单列表接口返回结果中取,所以这里选择flatMap操作符进行转换,而不是zip或者marge操作符进行并行的请求。此处flatMap操作符获取到的数据是订单列表,返回的是加工后(带状态值)的订单列表。
2、请求订单状态数据,并完成拼装数据
使用map操作符,将查询的状态结果和订单列表返回的数据进行匹配合并。
因为最终需要的还是订单列表,所以需要将查询状态接口返回的数据作为一个属性赋值给订单实体类,然后再返回订单列表。此处数据的转换使用map操作符。
注意:此处需要保证返回的订单列表数据是完整的,具体就是注意循环遍历的顺序和break。
3、接口错误时不抛出异常,不能影响订单列表的展示
使用OnErrorResumeNext操作符,保证查询状态的接口报错时不会发送onError事件,而且接口请求能正常结束。
使用FlatMap操作符并没有将两次请求合并为一次,本质上相当于将两个请求串行,订阅两次串行请求最终的结果。那么两次请求任何一个异常时还是会发送onError事件,那么正常情况下就会触发错误回调,进而显示错误页面。这个需求中,我们应该保证订单列表正常显示,所以查询状态接口报错时,不应该触发错误回调,那么我们就不能让他发送错误事件。OnErrorResumeNext操作符,可以在Observable触发OnError事件时进行拦截,同时转到备用的Observable,从而保证不会发送OnError事件。
这个例子里面我们发送了一个空数据和一个onComplete事件:
.onErrorResumeNext(observer -> {
//返回一个空的结果
observer.onNext(new MicroResponse<>());//正常结束当前的Observable
observer.onComplete();
})