RxJava遍历列表调用API返回原对象:移除blockingFirst()方案咨询
重构RxJava代码移除blockingFirst()
原代码在map操作里用blockingFirst()同步阻塞获取异步API结果,既破坏了RxJava的异步流特性,还可能引发线程阻塞问题。下面是完全基于RxJava异步链式调用的重构方案:
重构思路
- 将搜索结果中的列表项拆分为Observable流的单个元素,替代原有的同步遍历逻辑
- 对需要补充详情的列表项,用
flatMap发起异步API请求,拿到结果后更新item - 将处理完成的所有item重新收集为列表,再组装回原搜索结果对象
- 全程保持异步流的链式调用,不阻塞任何线程
重构后的完整代码
mDataRepository.getSearchResult(String.valueOf(searchQuery)) .subscribeOn(SchedulerFactory.get().getContentScheduler()) // 保留原有非空校验逻辑 .filter(searchResultList -> searchResultList != null && searchResultList.contents != null && searchResultList.contents.list != null) // 将列表拆分为单个item的Observable流 .flatMapIterable(searchResultList -> Arrays.stream(searchResultList.contents.list) .filter(Objects::nonNull) .collect(Collectors.toList()) ) // 异步处理每个item的详情更新 .flatMap(contentItem -> { if (VLOG_TYPE == contentItem.type) { // 异步获取vlog详情并更新item return mDataRepository.getVlogInfo(contentItem.type) .defaultIfEmpty(new Vlog()) .map(vlog -> { contentItem.description = vlog.description; return contentItem; }); } else { // 无需更新的item直接返回 return Observable.just(contentItem); } }) // 收集所有处理后的item为列表 .toList() // 将新列表组装回原搜索结果对象 .map(updatedItems -> { // 若原对象为可变类型,可直接替换list字段;若为不可变类型则创建新对象 SearchResultList result = new SearchResultList(); result.contents = new Contents(); result.contents.list = updatedItems.toArray(new ContentItem[0]); // 复制原对象其他字段(如果有) // result.otherField = originalSearchResult.otherField; return result; });
关键说明
- 用
flatMapIterable替代同步遍历,将列表转换为Observable流,实现每个item的异步独立处理 - 通过
flatMap处理异步API请求,确保所有操作都在RxJava的异步调度下执行,避免线程阻塞 - 最后用
toList()收集结果并映射回原结构,保证最终返回的对象结构与原需求一致
内容的提问来源于stack exchange,提问作者nightfixed
相关产品推荐
相关产品推荐

