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>
:
Здесь мы видим, что нам нужен оператор для 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 .