reactive-programming - 如果找到值但不执行其他步骤,则返回 Mono.empty()
问题描述
这个问题很难用文字来描述,所以如果标题不符合要求,很抱歉。
我想用 Project Reactor Flux 和 Mono 来实现一个特定的目标,乍一看似乎很简单。
“阻塞方式”中的代码示例将比长描述更好:
fun findGroupToCreateBlocking(userId: UUID, groupLabel: String): Optional<LinkUserToGroup> {
val group = lib.findGroupsOfUser(userId)
.flatMapIterable { it.items }
.filter { it.label == groupLabel }
.toMono()
.blockOptional()
if(group.isPresent) {
return Optional.empty()
}
return lib.searchGroups(groupLabel)
.flatMapIterable { it.items }
.filter { it.label == groupLabel }
.toMono()
.map { LinkUserToGroup(userId, it.id) }
.switchIfEmpty { IllegalStateException("Group $groupLabel not found").toMono() }
.blockOptional()
}
当然,我尝试在没有这block
部分的情况下实现相同的目标。我最终得到以下代码:
fun findGroupToCreateReactive(userId: UUID, groupLabel: String): Mono<LinkUserToGroup> =
lib.findGroupsOfUser(userId)
.flatMapIterable { it.items }
.filter { it.label == groupLabel }
.toMono()
.map { Optional.of(it) }
.defaultIfEmpty(Optional.empty())
.filter { g -> g.isEmpty }
.flatMap { lib.searchGroups(groupLabel)
.flatMapIterable { it.items }
.toMono()
.map { LinkUserToGroup(userId, it.id) }
.switchIfEmpty { IllegalStateException("Group $groupLabel not found").toMono() }
}
我认为(而且我不是唯一一个)我们可以做得更好,而不是依赖于Optional
流中间的使用......但我没有找到任何其他解决方案。
这是我第四次与这种“模式”作斗争,所以欢迎一些帮助!
我已经在 Gitlab (这里) 上生成了一个演示项目,其中包含对机器人反应和阻塞实现的单元测试,以查看命题是否符合要求。如果需要,您可以分叉并使用该项目。
解决方案
我没有使用 a Mono.empty
,而是使用了该Flux.hasElement
方法(如@yossarian),但添加了一个否定过滤器。它似乎可以工作,因为单元测试仍然通过。
fun findGroupToCreateReactive(userId: UUID, groupLabel: String): Mono<LinkUserToGroup> =
lib.findGroupsOfUser(userId)
.flatMapIterable { it.items }
.map { it.label }
.hasElement(groupLabel)
.filter { g -> !g }
.flatMap { lib.searchGroups(groupLabel)
.flatMapIterable { it.items }
.toMono()
.map { LinkUserToGroup(userId, it.id) }
.switchIfEmpty { IllegalStateException("Group $groupLabel not found").toMono() }
}
由于我们只想在用户不属于某个组时才搜索组,因此使用否定过滤器会更加明确。
推荐阅读
- python - 如何在 Google Cloud Platform 虚拟机中导入 Selenium?
- swift - GameKit:使用时与插件的连接中断
- python - 如何在每行中打印一个字符串,从行的第一行开始有一些空格?
- c++ - 为什么使用 QQuickWindow::grabWindow() 会导致窗口变成图像?
- java - 检测用户何时进入圈子
- java - 如何使用 JUnit5 模拟 System.getenv()
- java - Java/ JavaFX Server-多客户端聊天程序
- php - 为什么我使用 session_start() 时我的 PHP 文件停止执行?
- azure-eventgrid - 即使使用正确的(?)正文和 HTTP 状态代码 200,将 blobcreated webhook 的订阅者添加到事件网格也会失败
- c# - 架构问题 - 反向客户端和服务器