flatMap() vs subscribe() in Spring webflux

12,326
mono.subscribe(stores::addAll);

is asynchronous. That means, you tell the mono that it can now start evaluating.

What you do is continue processing stores right away - with a huge chance that the Mono hasn't evaluated yet.

So, how can you fix this?

You can block until the Mono has completed:

mono.doOnNext(stores::addAll).block()

Of course, this defeats the purpose of reactive programming. You are blocking the main thread until an action completes, which can be achieved without Reactor in a much simpler fashion.


The right way is to change the rest of your code to be reactive too, from head to toe. This is similar to your second example, where your call to dataexchange is part of the Mono, thus being evaluated asynchronously, too.

The important lesson to be learned is that operations like map or flatMap are not operating on the result of the Mono, but create a new Mono that adds another transformation to the execution of the original Mono. As long as the Mono doesn't evaluate, the flatMap or map operations are not actually doing anything.


I hope this helps.

Share:
12,326
XYZ
Author by

XYZ

Updated on June 09, 2022

Comments

  • XYZ
    XYZ almost 2 years

    I am a newbie to Spring WebFlux and trying to convert my spring MVC application to webflux. I return a Mono mono from my service :

        List<Store> stores = new ArrayList();
    

    When I do:

        mono.subscribe(stores::addAll);
        dataexchange.put("stores", stores);
        return Mono.just(dataexchange);
    

    Then stores is populated as empty list in response. However, I can verify that subscribe() is working after returning response.

    When I do :

        return mono.flatmap( (response) -> {
            dataexchange.put("stores", response));
            return Mono.just(dataexchange);
        });
    

    Then stores is populated in the response.

    Can someone please explain me what is the difference between the two? Is flatMap blocking? Thanks in advance !

  • XYZ
    XYZ over 5 years
    So, that means that flaptmap isn't blocking? Also, I have read in a number of articles that "Nothing happens until you subscribe" , i.e. no data flow is available until you subscribe. Then how does flatmap work without subscribe() ?
  • Markus Appel
    Markus Appel over 5 years
    @XYZ I can't tell from your example where you return your Mono to, but it absolutely shouldn't.
  • XYZ
    XYZ over 5 years
    I am returning this mono directly from controller. Can you please answer why flatmap() works without subscribe()?
  • Markus Appel
    Markus Appel over 5 years
    @XYZ it doesn't. Try it in a sandbox environment (without any controllers and other side effects). I think Spring handles the Mono when you return it by subscribing to it.
  • Ivan Rodrigues
    Ivan Rodrigues about 2 years
    I was facing the same issue but doing a search in documentation of mongoDB using reactive driver. There are an example using CountDownLatch. After use the CountDownLatch I can see all steps from log of Webflux. Before I can`t