问题描述
您可以将此反应性方法转换为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
更新
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)
存在时,它可以正常工作。如果不这样做,它会退出解析(不执行其他操作),而不是为val client分配null,因此我无法从解析内部启动异常,我猜这是正常的。
考虑以下方法,在该方法中,我需要控制两种情况,即客户端或项目不存在:
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)
解决方法
您应该将所有操作都转换为Flux,clientRepository.findById(clientId).toFlux().k()
此外,您无需抛出该异常即可打破束缚。
!ClientDoesntExistException(clientId).toMono<ApplicationOut>().k()