в чем разница между map и doOnNext в flux? (т.е. проектный реактор)

В Flux функция карты также выполняется для каждого элемента в потоке. Для doOnNext функция также выполняется для каждого элемента (испускаемого) в потоке. в чем разница с точки зрения пользователя? почему существует два подобных метода? Мог бы объяснить с простотой использования.

1 ответ

TL; DR;Flux#doOnNext для побочных эффектов,Flux#map предназначен для синхронного отображения чего-либо из одного типа в другой.

Если мы посмотрим на документацию, то дляdoOnNext

Flux<T> doOnNext(Consumer<? super T> onNext)
Add behavior (side-effect) triggered when the Flux emits an item.

это означает в doOnNext, мы можем выполнять побочные эффекты, такие как журнал, или делать где-нибудь вызов отдыха и т. д. и т.д. Мы также возвращаем поток типа T, который является тем же doOnNext принимает, поэтому никаких изменений типа.

Если мы с другой стороны посмотрим на Map:

Flux<V> map(Function<? super T,? extends V> mapper)
Transform the items emitted by this Flux by applying a synchronous function to 
each item.

Мы можем прочитать, что здесь мы можем применить синхронную функцию, в основном мы можем что-то сделать с нашим выданным значением. Добавьте что-то, вычтите что-то, измените это как-нибудь, здесь мы можем это преобразовать, напримерmap это к чему-то другому.

Если мы посмотрим на типы в map, мы видим, что map испустит что-нибудь super T но он вернет то, что extends V

Это типичный шаблон java-дженериков, и если вы хотите узнать больше об этом, я рекомендую вам посмотреть, как Джошуа Блохс говорит о дженериках. Все видео - хорошие часы, которые объяснят это гораздо лучше, чем я.

Но я хочу отметить, что, используя карту, вы возвращаете другой тип. Вы получаете то, чтоsuper T из потока, вы затем сопоставляете его с чем-то еще, что extends V.

Просто чтобы добавить к хорошему ответу выше - я думаю, что одна важная часть, которую мне не хватало, когда я начал использовать doOnNext() в том, что это не "потребительский" аналог "функционального" map и flatMap.

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

Mono.from()
    .doOnNext(doSomethingConsumer)
    .doOnNext(thenDoSomethingElseConsumer);

когда меня не интересует возвращаемое значение и что эти вещи будут применяться по порядку.
Это совершенно неверно! Фактически, оба doOnNext() Операторы применяются немедленно.

Другие вопросы по тегам