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

Reactor框架中上游报错时then()仍被调用的原因及正确实现方案

问题原因

核心差异在于混淆了Java方法的立即执行和响应式Publisher的订阅执行两个逻辑:

  • 编写.then(doSomethingElse())代码时,doSomethingElse()作为Java方法会在响应式流组装阶段就被直接调用,而非等待上游doSomething()返回的Mono执行完成后才触发,因此方法内的System.out.println("doSomethingElse")会在流组装时就执行输出,和上游是否报错没有关联。
  • then()方法仅控制是否订阅传入的Publisher,不会控制入参本身的执行时机。当前写法下哪怕上游报错、then没有订阅doSomethingElse()返回的Mono,方法内的打印逻辑也已经在组装阶段执行完成,所以会出现多余的输出。

正确实现方案

要实现「上游无报错才执行doSomethingElse()」的效果,需要把doSomethingElse()的调用包裹在懒加载逻辑中,让它仅在then需要订阅对应Publisher时才触发执行,常用写法有两种:

  1. 使用Mono.defer做懒加载包裹
doSomething()
    .then(Mono.defer(() -> doSomethingElse()))
    .onErrorResume(throwable -> {
        System.out.println("Error occurred");
        return Mono.empty();
    })

Mono.defer会把内部方法的执行延迟到有订阅者订阅时才触发,上游报错时不会触发对defer内Mono的订阅,doSomethingElse()就不会被调用。

  1. 改用flatMap实现相同语义(适合上游返回元素非空的场景,Void场景下也可兼容)
doSomething()
    .flatMap(unused -> doSomethingElse())
    .onErrorResume(throwable -> {
        System.out.println("Error occurred");
        return Mono.empty();
    })

flatMap的转换函数仅在上游正常发射元素时才会被调用,上游报错时不会进入转换函数,自然不会执行doSomethingElse()。

内容的提问来源于stack exchange,提问作者Toro Boro

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 00:27:07