21

What is the principal difference between these in terms of Mono? From the documentation, I read that flatMap acts asynchronous and map synchronous. But that doesn't really make sense for me b/c Mono is all about parallelism and that point isn't understandable. Can someone rephrase it in a more understandable way?

Then in the documentation for flatMap stated (https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Mono.html#flatMap-java.util.function.Function-):

Transform the item emitted by this Mono asynchronously, returning the value emitted by another Mono (possibly changing the value type). 

Which another Mono is meant there?

2 Answers 2

34

Mono#flatMap takes a Function that transforms a value into another Mono. That Mono could represent some asynchronous processing, like an HTTP request.

On the other hand, Mono#map takes a Function that transforms a value of type T into another value, of type R. That transformation is thus done imperatively and synchronously (eg. transforming a String into an URL instance).

The other subtlety with flatMap is that the operator subscribes to the generated Mono, unlike what would happen if you passed the same Function to map.

Sign up to request clarification or add additional context in comments.

4 Comments

does it mean that if I use Mono#map the transformation will be applied immediately without waiting for a subscription? And with Mono#flatMap it will be executed first after a subscriber is there? I don't really understand why would I need to create a new Mono with flatMap.
Another question, am I right, that Mono#map, #flatMap doesn't have directly to do with the java.util.stream.Stream's #map and #flatMap?
they do relate to Stream methods! Stream#flatMap collects the values from the inner streams and flattens them in the resulting Stream. In reactive types, the "collecting" part implies subscribing. The only difference is that in Mono#flatMap there is only at most one value to flatten, so a closer method would be Mono#flatMapMany (which results in a Flux)
The bottom line, your transformation function inside Mono#flatmap should return a Publisher (Mono) for flatMap operator to subscribe to. This is the syntactical difference. The other main (more imp) diff is that if your transformational function involves blocking calls, you are better off using flatMap so that the Publisher it returns can continue the async processing under the hood making your pipeline end to end async. On the other hand, the map will just block the thread thereby affecting the pipeline's async behavior.
0

I would say it simply,

map(a -> b) is returning Mono.just(b) 

map wraps the returned value in another mono whereas flatmap already expects a Mono do no further wrapping required

Practical use case example,

public Mono<String> getResponseFromServer(Mono<String> request) { // here few logics request.flatMap(r -> callServer(r); } 

Where callServer looks like

public Mono<String> callServer(String body) { // invoke http return http call returned mono } 

Above use case is not possible with map.

2 Comments

Note missing right-parenthesis. Presumably should be: request.flatMap(r -> callServer(r));
This take is very wrong. It is not just a utility method that wraps the result in a Mono. map executes the code synchrounously, whereas flatMap executes it asynchronously.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.