我正在尝试找出执行以下操作的正确方法。
- 我想通过
name
检查数据库中是否存在记录,这是一个全局二级索引。(假设主键是id
(。 - 如果已存在具有
name
的项目,则记录id
并name
并返回错误。 - 如果没有具有给定
name
的项目,请继续。
现在,代码结构如下所示。
private fun checkExistingData(name: String): Mono<QueryResponse> {
return repo.getDataByName(name)
.filterWhen { Mono.just(!it.hasItems()) }
.switchIfEmpty {
// log the existing id and name from QueryResponse
Mono.error(SomeCustomException))
}
.flatMap {
// proceed
}
}
如您所见,如果我想在switchIfEmpty
子句中记录id
,我需要在其中执行repo.getDataByName(name)
才能检索项目并获取项目的id
。显然,这是低效的,因为我在switchIfEmpty
之前已经这样做了。
正确的方法是什么?
等待有关QueryResponse
API的更多信息,我将假设几件事: -getDataByName
返回一个Mono<QueryResponse>
。这个Mono
总是被重视的,即它总是发出一个QueryResponse
无论是否可以找到数据 -QueryResponse#items
是我将在我的示例中用来正确访问行的内容。我还要假设它返回一个Flux<Item>
首先,filterWhen
在这里没有用,因为我们也有filter(boolean)
方法。我认为反向过滤逻辑可能更难遵循。
为什么不做flatMap
中的所有事情呢?
private fun checkExistingData(name: String): Mono<QueryResponse> {
return repo.getDataByName(name)
.flatMap {
if (it.hasItems())
it.items()
.single()
.doOnNext(existing -> logExisting(existing.id(), existing.name())
.then(Mono.error(SomeCustomException)
else
proceed()
}
}
如果对repo.getDataByName
的第一次调用返回Mono
并且此Mono
为空,则无需筛选该情况,因为不会调用管道的其余部分。所以我认为你可以保留switchIfEmpty()
来记录这个特殊情况,然后继续你的管道flatMap()
:
private fun checkExistingData(name: String): Mono<QueryResponse> {
return repo.getDataByName(name)
.switchIfEmpty {
// log the existing id and name from QueryResponse
Mono.error(SomeCustomException))
}
.flatMap {
// proceed
}
}