反应器 - 如何使用过滤器何时,如果它没有通过过滤器,仍然传递用于日志记录目的的值?



我正在尝试找出执行以下操作的正确方法。

  • 我想通过name检查数据库中是否存在记录,这是一个全局二级索引。(假设主键是id(。
  • 如果已存在具有name的项目,则记录idname并返回错误。
  • 如果没有具有给定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之前已经这样做了。

正确的方法是什么?

等待有关QueryResponseAPI的更多信息,我将假设几件事: -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
}
}

最新更新