Как использовать моно в другом моно с круговой зависимостью - PullRequest
0 голосов
/ 29 сентября 2018

У меня есть реактивное приложение с пружинной загрузкой.Где я хочу реализовать, чтобы создать пользователя, если он еще не существует.Вот так:

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 должен знать, существует ли оно уже и возвращает моно.

Ответы [ 2 ]

0 голосов
/ 10 октября 2018

Проблема заключалась в том, что я использовал filter() вместо того, чтобы использовать filterWhen(), который оценивает асинхронный монос.

Что я сделал:

fun create(userDTO: Mono<UserDTO>): Mono<Void> {
    return userDTO.filterWhen { innerUserDTO ->
        userRepository.existsByNameIgnoreCase(innerUserDTO.username).map { !it }
    }
            .flatMap { createNewUser(it) }
            .switchIfEmpty(userAlreadyExist())
            .then()
}
0 голосов
/ 01 октября 2018

Логика здесь выглядит немного странно - вы, вероятно, можете сделать что-то вроде:

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