您可以使用 Arrow FX 将此代码转换为 monad 理解吗?
Can you convert this code to monad comprehensions using Arrow FX?
你能把这个反应式方法转换成 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 客户端,而是退出理解(else 不执行)所以我无法从理解内部启动我的异常,我想这是正常的。
考虑以下方法,其中我需要控制客户或项目不存在的两种情况:
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()
你能把这个反应式方法转换成 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 客户端,而是退出理解(else 不执行)所以我无法从理解内部启动我的异常,我想这是正常的。
考虑以下方法,其中我需要控制客户或项目不存在的两种情况:
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()