【发布时间】:2020-11-08 14:11:58
【问题描述】:
你能把这个反应式方法转换成Arrow Fx Project Reactor monad comprehension吗?
class ApplicationServiceImpl(private val applicationRepository: ApplicationRepository,
private val clientRepository: ClientRepository) : ApplicationService {
override fun findByProjectId(clientId: String, projectId: String): Flux<ApplicationOut> {
return clientRepository.findById(clientId)
.switchIfEmpty(ClientDoesntExistException(clientId).toMono())
.flatMapMany { client ->
applicationRepository.findByProjectIdOrderByNameAsc(projectId).map {
it.convertToApplicationOut(client.timeZone)
}
}
}
}
我尝试过类似的方法,但它无效。
我发现的第一个问题是,最初我使用 flatMapMany 将 Mono 转换为 Flux。如果我使用FluxK.monad().fx.monad clientRepository.findById(clientId).k().bind() 没有可用的.bind() 函数。
如果我改用MonoK.monad().fx.monad,我不知道如何将输出转换为 Flux:
override fun findByProjectId(clientId: String, projectId: String): Flux<out ApplicationOut> {
return FluxK.monad().fx.monad {
val client = clientRepository.findById(clientId).k().bind()
if (client != null) {
!applicationRepository.findByProjectIdOrderByNameAsc(projectId)
.map { it.convertToApplicationOut(client.timeZone) }.k()
} else {
throw !ClientDoesntExistException(clientId).toMono<ApplicationOut>().k()
}
}.fix().flux
更新
按照 El Paco 的回答,我将代码修改为:
return FluxK.monad().fx.monad {
val client = !clientRepository.findById(clientId).toFlux().k()
if (client != null) {
!applicationRepository.findByProjectIdOrderByNameAsc(projectId)
.map { it.convertToApplicationOut(client.timeZone) }.k()
} else {
!ClientDoesntExistException(clientId).toFlux<ApplicationOut>().k()
}
}.fix().flux
clientRepository.findById(clientId) 存在时可以正常工作。如果没有,它不会将 null 分配给 val 客户端,而是退出理解(否则不执行),因此我无法从理解内启动我的异常,我想这是正常的。
考虑下面的方法,我需要控制两种情况下客户端或项目不存在:
return clientRepository.findById(clientId)
.switchIfEmpty(ClientDoesntExistException(clientId).toMono())
.flatMapMany { client ->
applicationRepository.findByProjectIdOrderByNameAsc(projectId)
.switchIfEmpty(ClientDoesntExistException(projectId).toMono())
.map { it.convertToApplicationOut(client.timeZone) }
}
考虑到 if/else 方法不起作用,我如何在使用推导时处理那些不存在的情况?
我可以在理解之外使用 switchIfEmpty 运算符,但我不知道原因(客户端不存在与项目不存在)
return FluxK.monad().fx.monad {
val client = !clientRepository.findById(clientId).toFlux().k()
!applicationRepository.findByProjectIdOrderByNameAsc(projectId)
.map { it.convertToApplicationOut(client.timeZone) }.k()
}.fix().flux
.switchIfEmpty(XXX)
【问题讨论】:
标签: kotlin project-reactor arrow-kt