You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot 3.x WebFlux:如何将循环中Mono<String>转为List<String>

解决Spring WebFlux中合并Mono为List的问题

原代码的问题

  • Flux是不可变对象,IdFlux.concat(IdMono1)会返回一个新的Flux实例,你没有将这个新实例赋值给IdFlux,导致原IdFlux始终是空的。
  • 使用parallelStream().forEach()结合响应式操作是错误的:响应式操作是异步非阻塞的,forEach的同步遍历无法正确追踪异步操作的完成状态,还会破坏响应式流的链式调用逻辑。
  • 你定义的Flux<Mono<String>>是嵌套的响应式类型,最终需要的是直接包含字符串的Flux<String>,再转换为List。

正确实现方式

响应式非阻塞写法(推荐)

直接将keySet转换为Flux,通过flatMap展开每个Mono<String>为字符串流,最后收集为List:

// 将keySet转为Flux,基于响应式流处理每个key
Flux<String> idFlux = Flux.fromIterable(matchesByComp.keySet())
    // flatMap自动将Mono<String>展开为Flux的元素,支持并行处理Redis请求
    .flatMap(key -> reactiveRedisOperations.get(key, id));

// 收集所有字符串为List,返回Mono<List<String>>
Mono<List<String>> idListMono = idFlux.collectList();

// 在WebFlux Controller中可直接返回Mono<List<String>>,框架会自动处理订阅和响应
// return idListMono;

同步获取List(仅允许阻塞的场景使用)

如果必须同步获取List(比如测试代码、非WebFlux主线程),可以使用block()方法(注意:WebFlux应用主线程中使用block会阻塞线程,违背响应式设计原则):

List<String> idList = idListMono.block();

额外说明

  • 如果需要顺序处理每个Redis请求(而非并行),可以将flatMap替换为concatMap,但concatMap是串行执行,性能会低于flatMap。
  • 永远不要在WebFlux的请求处理线程中使用block(),否则会耗尽线程池资源,导致应用性能急剧下降。

内容的提问来源于stack exchange,提问作者Amulya M

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 22:28:13