【问题标题】:How to use a mono in another mono that have circular dependency如何在另一个具有循环依赖的单声道中使用单声道
【发布时间】:2019-03-05 02:48:59
【问题描述】:

我有一个 Spring Boot 反应式应用程序。如果用户不存在,我想在哪里实现创建用户。像这样:

fun userAlreadyExist() = Mono.error<UserDTO>(UsernameAlreadyExistException())

fun create(userDTO: Mono<UserDTO>): Mono<Void> {
    return userDTO.filter { userRepository.existsByNameIgnoreCase(it.username).block() == false }
            .switchIfEmpty(userAlreadyExist())
            .flatMap { createNewUser(it).then() }

我真正不喜欢的是我需要在过滤器中使用.block()。有一个更好的方法吗?

最大的问题是两者都有循环依赖,因为UserRepository 需要知道用户名,而 userDTO 流需要知道这是否已经存在,这会返回一个单声道。

【问题讨论】:

    标签: spring-boot kotlin reactive-programming spring-webflux project-reactor


    【解决方案1】:

    这里的逻辑看起来有点奇怪——你可能可以这样做:

    fun create(userDTO: Mono<UserDTO>): Mono<Void> {
        return userDTO.flatMap {
                   userRepository.findByNameIgnoreCase(it.username)
                                 .flatMap(user -> userAlreadyExist())
                                 .switchIfEmpty(createNewUser(it)) 
               }.then()
    

    【讨论】:

    • 不幸的是,这不起作用。我还需要调用 userAlreadyExist() 因为它返回一个错误单声道private fun userAlreadyExist() = Mono.error&lt;UserDTO&gt;(UsernameAlreadyExistException())
    • 我已经编辑了我的答案;它看起来仍然有点复杂,应该改进。
    【解决方案2】:

    问题是我使用了filter(),而不是我应该使用的是filterWhen(),它评估异步Monos。

    我做了什么:

    fun create(userDTO: Mono<UserDTO>): Mono<Void> {
        return userDTO.filterWhen { innerUserDTO ->
            userRepository.existsByNameIgnoreCase(innerUserDTO.username).map { !it }
        }
                .flatMap { createNewUser(it) }
                .switchIfEmpty(userAlreadyExist())
                .then()
    }
    

    【讨论】:

      猜你喜欢
      • 2010-12-15
      • 1970-01-01
      • 1970-01-01
      • 2023-03-07
      • 1970-01-01
      • 1970-01-01
      • 2022-09-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多