Reactor - 如果它没有通过过滤器,如何使用 filterWhen 并仍然传递用于记录目的的值?
Reactor - How to use filterWhen and still pass the value for logging purposes if it doesn't pass the filter?
我正在尝试找出执行以下操作的正确方法。
- 我想通过
name
检查数据库中是否存在记录,这是一个全局二级索引。 (假设主键是 id
)。
- 如果已经有一个项目具有
name
,则记录 id
和 name
以及 returns 错误。
- 如果没有符合给定
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
returns 一个 Mono<QueryResponse>
。这个 Mono
总是有价值的,即它总是发出一个 QueryResponse
无论是否可以找到数据
- QueryResponse#items
是我将在示例中用来正确访问行的内容。我还将假设它 returns a 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
returns a 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
}
}
我正在尝试找出执行以下操作的正确方法。
- 我想通过
name
检查数据库中是否存在记录,这是一个全局二级索引。 (假设主键是id
)。 - 如果已经有一个项目具有
name
,则记录id
和name
以及 returns 错误。 - 如果没有符合给定
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
returns 一个 Mono<QueryResponse>
。这个 Mono
总是有价值的,即它总是发出一个 QueryResponse
无论是否可以找到数据
- QueryResponse#items
是我将在示例中用来正确访问行的内容。我还将假设它 returns a 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
returns a 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
}
}