У меня есть список Mono, некоторые из которых завершают некоторые неудачи:

Mono<String> success1 = Mono.just("hello");
Mono<String> success2 = Mono.just("world");
Mono<String> error1 = Mono.error(new IllegalArgumentException("error1"));
Mono<String> error2 = Mono.error(new IllegalArgumentException("error2"));
List<Mono<String>> monos = Arrays.asList(success1, success2, error1, error2);

Из этого списка, как собрать успешные и неудачные Monos за один присест? (это означает, что каждый моно излучает только один раз)

private Mono<Result> collectMonoListResult(List<Mono<String>> monos) {
   // TODO what comes here
   // so that the result will have "hello" and "world" in the successList
   // and 2 IllegalArgumentException instances on the errorList?
}

@AllArgsConstructor
class Result {
   private List<String> successList;
   private List<Throwable> errorList;
}
1
nagy.zsolt.hun 21 Фев 2021 в 23:26

1 ответ

Лучший ответ

Одно из решений - материализовать каждый Mono, объединить их в Flux и собрать результаты.

    private <T> Mono<Result<T>> collectMonoListResult(List<Mono<T>> monos) {
        return monos.stream()
                // Materialize each Mono<T> into a Mono<Signal<T>>
                // to be able to obtain the emitted element or error.
                .map(Mono::materialize)
                // Merge all the Mono<Signal<T>> into a Flux<Signal<T>>
                .<Flux<Signal<T>>>reduce(Flux.empty(), Flux::mergeWith, Flux::mergeWith)
                // Collect all the Signals into a single Result
                .collect(Result::new, (result, signal) -> {
                    if (signal.isOnNext()) {
                        result.addSuccess(signal.get());
                    } else if (signal.isOnError()) {
                        result.addError(signal.getThrowable());
                    }
                });
    }

    public static class Result<T> {
        private final List<T> successList = new ArrayList<>();
        private final List<Throwable> errorList = new ArrayList<>();

        public void addSuccess(T success) {
            successList.add(success);
        }
        public void addError(Throwable error) {
            errorList.add(error);
        }

        public List<T> getSuccessList() {
            return Collections.unmodifiableList(successList);
        }

        public List<Throwable> getErrorList() {
            return Collections.unmodifiableList(errorList);
        }
    }


0
Phil Clay 22 Фев 2021 в 01:44