RxJava批量发起接口请求时如何忽略失败请求、保留正常返回结果?
问题分析
你当前的实现使用zip操作符合并所有请求,zip的特性是必须所有关联的Observable都正常发射数据才会触发合并逻辑,任意一个请求报错都会直接终止整个流,你把onErrorResumeNext加在zip流的下游,只能在整个流完全失败时返回空列表,无法实现单个失败请求的忽略。
实现方案
核心思路是给每个单独的请求做错误捕获,不让单个请求的错误传导到整个流,再把所有成功返回的结果收集成列表即可,推荐用fromIterable + flatMap + toList的组合实现,修改后代码如下:
private void getMoreArticles(List<Integer> l) { ApiInterface apiInterface = ApiClient.getApiClientRX().create(ApiInterface.class); Observable.fromIterable(l) // flatMap并发请求,第二个参数可选,指定最大并发数避免请求过多 .flatMap(id -> apiInterface.getArticle1(id) // 单个请求出错时直接返回空Observable,跳过该请求 .onErrorResumeNext(throwable -> Observable.empty()), 5) // 把所有成功返回的Articles结果收集为列表 .toList() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe( articlesList -> { adapter = new Adapter(articlesList, MainActivity.this); if (fav) recyclerView.setAdapter(adapter); else addRV().setAdapter(adapter); adapter.notifyDataSetChanged(); initListener(); swipeRefreshLayout.setRefreshing(false); }, e -> { // 此处的错误仅为流程级错误,单个请求的错误已经被提前捕获 swipeRefreshLayout.setRefreshing(false); } ).isDisposed(); }
改动说明
- 去掉了原来手动构建请求列表+zip的逻辑,改用
Observable.fromIterable直接遍历ID列表,代码更简洁 - 每个
getArticle1请求都单独加了onErrorResumeNext,出错时直接返回空Observable,既不会抛出错误中断整个流,也不会把无效结果加入最终列表 - 用
toList()自动收集所有正常返回的文章对象,最终得到的列表就是所有请求成功的结果
如果你坚持要使用zip实现,也可以给每个请求加onErrorResumeNext返回一个占位的null对象,然后在zip的合并函数中过滤掉null值即可,上述方案逻辑更简单,性能和zip实现一致。
内容的提问来源于stack exchange,提问作者Patryk
相关产品推荐
相关产品推荐

