需求:资料下载页面,有一个一键批量下载功能,但是为了下载安全性考虑,每个下载都需要请求服务器动态生成一个下载的token,这就需要我们有多少个资料就调用多少次获取token的接口了。
实现代码:
Observable<List<MicroResponse<DownloadToken>>> observable =
//1、依次发送资料列表数据
Observable.fromIterable(listDoc)
//根据资料数据生成下载token
.flatMap(new Function<DocBean, ObservableSource<MicroResponse<DownloadToken>>>() {
@Override
public ObservableSource<MicroResponse<DownloadToken>> apply(DocBean docBean) throws Exception {
//请求接口,生成DownloadToken
return mModel.createDownloadToken(docBean.docId);
}
})
//2、通过buffer操作符将多个请求的结果合并
.buffer(listDoc.size());
//订阅
observable
.safeSubscribe(new SimpleSubscriber<List<MicroResponse<DownloadToken>>>() {
@Override
public void onNext(List<MicroResponse<DownloadToken>> resp) {
//遍历所有结果,开始下载
}
});
解析:
1、依次发送资料列表数据
FromIterable操作符可以将列表数据依次发送出来,直到发送完所有数据。
这里使用FromIterable操作符替代for循环实现依次发送请求的动作,优点在于可以和其他Rxjava的操作符结合,而且数据流转换数据本身更便于理解。
2、通过buffer操作符将多个请求的结果合并
Buffer操作符起到一个缓冲的作用,将等待所有的事件都发送完成后,将所有的结果以集合的形式一起返回。
如果我们采用for循环去发送请求的话,那么对于返回结果的处理和管理都是不晓得工作量,而且为了获取所有请求结果都返回了,这个状态就需要加额外的计数、状态等字段来判断。通过FromIterable和Buffer操作符配合就完美解决了这个问题,可以订阅到所有请求都完成的时机,直接拿到所有的请求结果。
注意:因为这里请求很多,也需要考虑有个别请求异常的情况发生,可以使用OnErrorResumeNext操作符发送默认值来解决。