需求:订单列表接口返回多种类型的订单,在某个页面我们只需要过滤出某种类型的订单来展示。
假设此时接口又不支持这种过滤,需要我们前端自己处理😂,那么我们可以通过Filter结合其他操作符对返回结果进行过滤。当然这里也可以不使用操作符,直接请求到列表数据后,再遍历筛选数据。那使用操作符的最大优势就是将过滤数据的操作前置(订阅前就定义好过滤逻辑了),达到的效果就是对于订阅者来说是无感知的。
Observable<List<OrderInfo>> observable = mModel.getAllOrderList()
//1、通过flatMap对结果进行转换
.flatMap(new Function<List<OrderInfo>, ObservableSource<List<OrderInfo>>>() {
@Override
public ObservableSource<List<OrderInfo>> apply(List<OrderInfo> lstSource) throws Exception {
if (lstSource == null || lstSource.length==0) {
return Observable.just(new ArrayList<>());
}
//2、判断数据不为空后,用过fromIterable依次发送每个订单对象
return Observable.fromIterable(response.data)
// 3、通过filter自定义判断方法,确定哪些数据是有效的
.filter(new Predicate<OrderInfo>() {
@Override
public boolean test(OrderInfo orderInfo) throws Exception {
//4、简化判断条件(假设catalogId是"A"的,符合我们需要的条件)
return orderInfo.catalogId.equals("A");
}
})
//5、将过滤后的结果合并成列表发送
.buffer(response.data.size());
}
});
//订阅
observable.safeSubscribe(new SimpleSubscriber<List<OrderInfo>>() {
@Override
public void onNext(List<OrderInfo> resp) {
//遍历所有结果,开始下载
}
});
具体步骤解释:
1、通过flatMap对结果进行转换
通过flatMap转换后返回的还是可观察的Observable,所以转换后的结果是可以被订阅的。结合其他操作符链式调用,最终完成数据的转换。
2、判断数据不为空后,用过fromIterable依次发送每个订单对象
FromIterable可以依次发送集合中的数据,代替普通的循环并且保持数据流不中断。提前判空,减少不必要的过滤逻辑。
3、通过filter自定义判断方法,确定哪些数据是有效的
Filter操作符中接收一个Predicate对象,通过test方法返回结果决定数据是否符合要求。true:有效数据
false:无效数据
经过test测试后,将满足条件的结果发送出,不满足条件的数据舍弃掉。
4、简化判断条件(假设catalogId是"A"的,符合我们需要的条件)
这里判断条件是否成立决定filter操作符的过滤结果。
5、将过滤后的结果合并成列表发送
buffer可以通过设置缓冲数量为接口返回的数据总数,意思就是期望值是所有的数据都被整合到一起。因为缓冲数量必须大于0。所以在FromIterable之前先判一下集合是否为空。
注意:如果列表接口是分页的,明显前端过滤数据不是很合适,此时应该推动后端支持接口过滤数据。