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 user perspective? why two similar method exists? Could explain with simple use-ease.
[′fləks ‚map·iŋ] (nucleonics) The process of measuring the radiation flux at representative points within a nuclear reactor or around some other radiation source.
A Flux object represents a reactive sequence of 0.. N items, while a Mono object represents a single-value-or-empty (0..1) result. This distinction carries a bit of semantic information into the type, indicating the rough cardinality of the asynchronous processing.
A Reactive Streams Publisher with rx operators that emits 0 to N elements, and then completes (successfully or with an error). It is intended to be used in implementations and return types. Input parameters should keep using raw Publisher as much as possible.
By default, data production process starts on the Thread that initiated the subscription. Operators that deal with a time (e.g. Mono. delay ) will default to running on the Schedulers. parallel() scheduler.
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.
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 instans 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 watching 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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With