Reactor中处理Mono空值/无结果时执行逻辑的正确方式?
处理Mono无结果/异常场景的正确姿势
一、业务预期的无结果场景:用Mono.empty() + doOnEmpty()
如果“数据库无结果、API空响应”是业务上的正常情况(比如定时任务定期拉取数据,没查到数据属于预期内的场景),推荐用Mono.empty()配合doOnEmpty()处理,完全符合你“不需要返回内容、不触发subscribe逻辑”的需求:
Mono<MyObject> myObjectMono = Mono.empty(); // 模拟无结果场景 myObjectMono .doOnEmpty(() -> { // 这里写数据库无结果、API空响应时的特定逻辑 System.out.println("未查询到数据,执行预设逻辑"); }) .subscribe(myObject -> { // 只有当Mono发射有效元素时,才会执行这里的逻辑 System.out.println("处理获取到的数据:" + myObject); });
doOnEmpty()是专门用于处理Mono完成但未发射任何元素的副作用操作,不会改变流的结构,也不会触发subscribe的onNext回调,完美匹配你的需求。
二、异常场景:用Mono.error()处理
如果“API返回404”或无结果属于异常情况(比如业务逻辑要求必须存在对应数据,查不到则属于错误),则用Mono.error()抛出异常,再通过doOnError()或onErrorResume()处理:
// 模拟异常场景:比如API返回404、数据库查询出错 Mono<MyObject> myObjectMono = Mono.error(new NotFoundException("请求资源不存在")); myObjectMono .doOnError(NotFoundException.class, e -> { // 专门处理NotFound类型的异常(比如404、查不到数据的错误场景) System.err.println("触发未找到异常:" + e.getMessage()); }) .doOnError(e -> { // 处理其他类型的异常(比如数据库连接失败、API返回5xx等) System.err.println("发生未知错误:" + e.getMessage()); }) .subscribe( myObject -> { // 有有效数据时的处理逻辑 System.out.println("处理数据:" + myObject); }, error -> { // 可选:如果需要在订阅阶段捕获未被处理的错误,添加此回调 System.err.println("订阅阶段捕获错误:" + error.getMessage()); } );
注意:如果不想让错误继续传播,可以用onErrorResume()返回一个空Mono或默认值,但你的定时任务场景中,直接用doOnError()处理副作用即可。
核心语义区别总结
- Mono.empty():代表正常的无结果,业务逻辑预期内的“没有数据”,不属于错误。
- Mono.error():代表异常情况,业务逻辑外的错误(比如服务故障、资源不存在且违反预期)。
根据你的定时任务场景,优先判断无结果是否属于业务预期,再选择对应的方案即可。
内容的提问来源于stack exchange,提问作者crimson589
相关产品推荐
相关产品推荐

