2

The following code was about to first delete a KV from redis, and then set a new KV there and return. But it actually never set after delete. I only see mistake after print every log, as 2 any is MonoNext. Then I released a chain step before this any needs to split off one Mono, so I used flatMap instead of map at marker. This problem is more likely happened to me, especially when functions are deeply encapsulated inside another function with Mono in and out.

    @RequestMapping("addUserSimple3")
    public Mono<AddUserResponse> addUser3(@RequestBody Mono<AddUserVo> vo) {
        return vo.flatMap(v ->
                redisOps.delete(v.getGroupId())
                        .map(any -> {   <---------------------Use flatMap instead of map
                            log.info("1 any is {}", any);
                            return redisOps.set(v.getGroupId(), v.getPersonId());
                        })
                        .map(any ->
                        {
                            log.info("2 any is {}", any);
                            return new AddUserResponse(ResponseState.GOOD, v.getLogId());
                        })
        );
    }

Then my question is, how to better understand MonoNext and flatMap? (aka, I let the above code work by replacing map but I don't understand why it did not work, and why it does later)

Alex
  • 4,987
  • 1
  • 8
  • 26
Tiina
  • 4,285
  • 7
  • 44
  • 73
  • Does this answer your question? [Do you have a test to show differences between the reactor map() and flatMap()?](https://stackoverflow.com/questions/65689935/do-you-have-a-test-to-show-differences-between-the-reactor-map-and-flatmap) – Toerktumlare May 10 '22 at 19:08

1 Answers1

1

TL;DR In case operation is asynchronous (returns Mono or Flux) - use flatMap, for synchronous logic use map.

In reactive nothing happens until you subscribe. flatMap subscribes to the provided publisher, returning the value emitted by another Mono or Flux. map just transforms the value applying a synchronous function to it.

@RequestMapping("addUserSimple3")
public Mono<AddUserResponse> addUser3(@RequestBody Mono<AddUserVo> vo) {
    return vo.flatMap(v ->
            redisOps.delete(v.getGroupId())
                    .flatMap(res -> redisOps.set(v.getGroupId(), v.getPersonId()))
                    .map(res -> new AddUserResponse(ResponseState.GOOD, v.getLogId()))
    );
}
Alex
  • 4,987
  • 1
  • 8
  • 26