Я использую Kotlin и Стрела и WebClient от spring-webflux. Я бы хотел преобразовать экземпляр Мононуклеоз в Либо.
Экземпляр Either создается путем вызова Either.right(..), когда ответ WebClient успешен, или Either.left(..), когда WebClient возвращает ошибку.
Я ищу метод в Mono, похожий на Either.fold (..), где я могу сопоставить успешный и ошибочный результат и вернуть другой тип, нежели Mono. Примерно так (псевдокод, который не работает):
val either : Either<Throwable, ClientResponse> =
webClient().post().exchange()
.fold({ throwable -> Either.left(throwable) },
{ response -> Either.right(response)})
Как нужно действовать?





Я не очень хорошо знаком ни с этой библиотекой Arrow, ни с типичным сценарием ее использования, поэтому я воспользуюсь фрагментами Java, чтобы изложить здесь свою точку зрения.
Прежде всего, я хотел бы отметить, что этот тип вроде бы блокирующий, а не ленивый (в отличие от Mono). Перевод Mono в этот тип означает, что вы сделаете блокировку своего кода и что вы не должны этого делать, например, в середине обработчика контроллера, иначе вы заблокируете весь свой сервер.
Это более или менее эквивалентно этому:
Mono<ClientResponse> response = webClient.get().uri("/").exchange();
// blocking; return the response or throws an exception
ClientResponse blockingResponse = response.block();
При этом, я думаю, вы сможете преобразовать Mono в этот тип, либо вызвав на нем block() и блок try/catch вокруг него, либо сначала превратив его в CompletableFuture, например:
Mono<ClientResponse> response = webClient.get().uri("/").exchange();
Either<Throwable, ClientResponse> either = response
.toFuture()
.handle((resp, t) -> Either.fold(t, resp))
.get();
Могут быть более эффективные способы сделать это (особенно со встроенными функциями), но все они в первую очередь должны включать блокировку на Mono.
На fold нет метода Mono, но вы можете добиться того же, используя два метода: map и onErrorResume. Это будет примерно так:
val either : Either<Throwable, ClientResponse> =
webClient().post()
.exchange()
.map { Either.right(it) }
.onErrorResume { Either.left(it).toMono() }