如何判断Mono是否为空并分支处理?为何switchIfEmpty在有结果时执行?
问题原因与解决方案
为什么switchIfEmpty会被意外触发?
你遇到的问题核心是:switchIfEmpty监听的是它上游flatMap返回的Mono,而非repository.find()返回的Mono。如果你的flatMap代码块处理查询到的数据时,返回了Mono.empty(),上游就会变成空Mono,switchIfEmpty自然会被触发。
比如你在// Found something on the database里的逻辑如果是这样:
.flatMap { something -> // 错误示例:处理后返回空Mono Mono.empty() }
哪怕find()查到了数据,只要这个flatMap返回空,switchIfEmpty就会执行。
实现「存在更新、不存在插入」的正确写法
针对你的需求,正确的做法是让find()的结果直接分支:查到数据走更新逻辑,没查到走插入逻辑。代码结构如下:
// Iterating over 5 items... .flatMap { item -> repository.find(item.integration.id, item.integration.type) // 查到数据时执行更新 .flatMap { existingSomething -> // 编写更新逻辑,返回更新后的Mono<Something> repository.update(existingSomething) } // 没查到数据时执行插入 .switchIfEmpty(Mono.defer { // 创建要插入的对象,执行插入操作 val newSomething = Something(item.integration.id, item.integration.type, ...) repository.insert(newSomething) }) }
关键注意点:
switchIfEmpty里用Mono.defer()包裹插入逻辑:确保只有确实需要插入时,才会创建新对象和执行插入操作,避免不必要的资源消耗。- 保证
flatMap里的更新逻辑返回非空Mono:比如repository.update()应当返回更新后的实体对象的Mono,而非空Mono。
内容的提问来源于stack exchange,提问作者Rafa Acioly
相关产品推荐
相关产品推荐

