Перейти к основному содержимому

Как преобразовать Mono<List<T>> в Flux<T>

· 3 мин. чтения

1. Обзор

Иногда в реактивном программировании у нас может быть издатель большой коллекции элементов. В некоторых случаях потребители этого издателя могут не иметь возможности обрабатывать все элементы за один раз. Поэтому нам может потребоваться публиковать каждый элемент асинхронно, чтобы соответствовать скорости обработки потребителя.

В этом уроке мы рассмотрим некоторые способы, с помощью которых мы можем преобразовать наш Mono коллекции в Flux элементов коллекции .

2. Описание проблемы

При работе с Reactive Streams мы используем Publisher и две его реализации, Flux и Mono . Хотя Mono<T> — это тип Publisher<T> , который может выдавать 0 или 1 элемент типа T , Flux<T> может выдавать от 0 до N элементов типа T .

Допустим, у нас есть издатель Mono , который содержит Mono<List<T>> — итерируемую коллекцию элементов типа T. Наше требование состоит в том, чтобы создавать элементы коллекции асинхронно, используя Flux<T> :

./379ef55a11a590e89238f696fce9a6e4.png

Здесь мы видим, что нам нужен оператор для Mono<List<T>> , который может выполнять это преобразование. Сначала мы будем извлекать элементы коллекции из потокового издателя Mono , а затем создавать элементы один за другим асинхронно как Flux .

Издатель Mono содержит оператор карты , который может синхронно преобразовывать Mono , и оператор flatMap для асинхронного преобразования Mono . Кроме того, оба этих оператора производят один элемент в качестве вывода.

Однако в нашем случае использования для создания большого количества элементов после сведения Mono<List<T>> , мы можем использовать flatMapMany или flatMapIterable .

Давайте рассмотрим, как использовать эти операторы.

3. flatMapMany

Давайте начнем с примера List of String для создания нашего Mono Publisher :

private Mono<List<String>> monoOfList() {
List<String> list = new ArrayList<>();
list.add("one");
list.add("two");
list.add("three");
list.add("four");

return Mono.just(list);
}

FlatMapMany — это универсальный оператор в Mono , который возвращает Publisher. Давайте применим flatMapMany к нашему решению:

private <T> Flux<T> monoTofluxUsingFlatMapMany(Mono<List<T>> monoList) {
return monoList
.flatMapMany(Flux::fromIterable)
.log();
}

В этом случае flatMapMany берет список Mono , сглаживает его и создает издателя Flux с помощью оператора Flux fromIterable . Мы также использовали здесь log() для регистрации каждого произведенного элемента. Следовательно, это будет выводить элементы один за другим, например « один », « два », « три », « четыре », а затем завершаться . ** `` **

4. FlatMapIterable

Для того же примера List of String мы теперь рассмотрим flatMapIterable — специально созданный оператор.

Здесь нам не нужно явно создавать Flux из списка ; нам нужно только предоставить List . Этот оператор неявно создает Flux из своих элементов. Давайте используем flatMapIterable для нашего решения:

private <T> Flux<T> monoTofluxUsingFlatMapIterable(Mono<List<T>> monoList) {
return monoList
.flatMapIterable(list -> list)
.log();
}

Здесь flatMapIterable берет список Mono и внутренне преобразует его в поток его элементов. Следовательно, он более оптимизирован по сравнению с оператором flatMapMany . И это выведет те же самые « один », « два », « три », « четыре », а затем завершится . ** `` **

5. Вывод

В этой статье мы обсудили различные способы преобразования Mono<List<T>> в Flux<T> с помощью операторов flatMapMany и flatMapIterable . Оба являются простыми в использовании операторами. В то время как flatMapMany полезен для более общих издателей, flatMapIterable лучше оптимизирован для таких целей.

Как всегда, пример кода доступен на GitHub .