In Flux map
function is also executed for each item in the flux. For doOnNext
function is also executed for every item (emitted) in the flux. What is the difference from the user's perspective? Why do two similar methods exist? Could someone explain with a simple use-case?
TLDR;
Flux#doOnNext
is for side effects,
Flux#map
is for mapping something from one type to another type, synchronously.
If we look at the documentation it says the following for doOnNext
Flux<T> doOnNext(Consumer<? super T> onNext)
Add behavior (side-effect) triggered when the Flux emits an item.
this means in doOnNext
, we can do side effects, like log, or do a rest call somewhere etc. etc. We also return a Flux of type T
, that is the same that doOnNext
is taking in, so no type change.
If we on the other hand look at 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.
We can read that here we can apply a synchronous function, basically we can do something with our emitted value. Add something, deduct something, change it some way, here we can transform it, for instance map
it to something else.
If we look at the types in map
, we can see that map
will emit something super T
but it will return something that extends V
This is a typical Java generics pattern and if you wish to know more about just this, I recommend you watch Joshua Blochs talk about generics. The entire video is a good watch and will explain it much better than me.
But what I want to point out is that by using map
, you are returning a different type. You get something that super T
from the flux, you then map it to something else that extends V
.
map
you don't. –
Ediva Just to add to the other nice answer - I think the one important part that I was missing when I started using doOnNext()
is that it is not a "consumer" counter-part of "function-like" map
and flatMap
.
doOnNext
is sort of a callback that gets executed when a Publisher emits an item but it does not affect the flow, namely it returns the original Publisher immediately.
Example: initially I thought I could do things like
Mono.from()
.doOnNext(doSomethingConsumer)
.doOnNext(thenDoSomethingElseConsumer);
when I am not interested in the return value and that these things will be applied in order.
This is completely wrong! In fact, both doOnNext()
operators are applied immediately.
© 2022 - 2024 — McMap. All rights reserved.