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

合并可能返回Mono.empty()的多个Mono并聚合结果的技术实现问题

解决Reactor中Mono.zip因empty中断的聚合问题

这个问题我之前也碰到过——Mono.zip的行为确实容易让人踩坑,因为它严格要求所有源Mono都必须发射一个元素,只要有一个是Mono.empty(),整个zip流就会直接变成empty,根本走不到map那一步,自然拿不到你想要的聚合结果。

核心解决方案:将empty转换为null发射

要实现你想要的「即使某个Mono返回empty,也保留对应字段为null的聚合结果」,只需要给每个可能返回Mono.empty()的源Mono加上defaultIfEmpty(null)操作符,把empty状态转换成发射一个null值。这样每个Mono都会至少发射一个值(要么是原本的有效结果,要么是null),Mono.zip就能正常收集所有元素并完成聚合。

修改后的完整代码

fun main() {
    val mono1 = Mono.just(1)
    val mono2 = Mono.just("two")
    // 给empty的Mono加上defaultIfEmpty,将其转换为发射null
    val mono3 = Mono.empty<Boolean>().defaultIfEmpty(null)
    
    data class Aggregated(
        val f1: Int? = null,
        val f2: String? = null,
        val f3: Boolean? = null,
    )
    
    Mono.zip(mono1, mono2, mono3)
        .map { tuple -> Aggregated(tuple.t1, tuple.t2, tuple.t3) }
        .subscribe(
            { c -> logger.info { c.toString() } }, // 输出:Aggregated(f1=1, f2=two, f3=null)
            { e -> logger.error(e) { e.message } },
            { logger.info { ">> Done! " } }
        )
}

扩展:处理错误场景(可选)

如果你的Mono不仅可能返回empty,还可能抛出异常,想要把异常场景也对应到聚合字段的null,可以额外加上onErrorReturn(null)操作符:

// 同时处理empty和错误,统一返回null
val mono3 = Mono.error<Boolean>(RuntimeException("Oops!"))
    .onErrorReturn(null)
    .defaultIfEmpty(null)

这样无论Mono是empty还是抛出错误,都会给zip流提供一个null值,保证整个聚合流程不会中断。

内容的提问来源于stack exchange,提问作者Jonathan Handoyo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 13:07:39