WebFlux flatMap(map), doOnNext, doOnSuccess, then 차이

June Lee·2022년 10월 26일
1

Spring WebFlux

목록 보기
6/6

flatMap(혹은 map)과 doOnNext(혹은 doOnSuccess)의 차이

일단 flatMap과 doOnNext의 차이는,
flatMap은 앞에서 전달받은 아이템을 다른 형태로 변환하여 방출하는 반면, doOnNext는 로깅, api 콜과 같은 부가적인 동작을 하되, 전달받은 아이템을 변환하여 넘기는 동작은 하지 않는다는 점이다. 즉, source에 대한 transforming은 하지 않는다. (참고)

cf) map과 flatMap의 차이
map은 일반 개체를 반환하는 반면, flatMap은 publisher(Mono/Flux)를 반환한다.
또 map은 sync 연산자로, 호출자와 동일한 스레드에서 실행되고, 순서를 보장하는 반면,
flatMap은 sync / async 연산자로, 두 가지 동작이 모두 가능하다. (참고) -> 아마 flatMapSequential 같은 연산자도 있기 때문이 아닐까...?

cf) concatMap
concatMap은 flatMap과 동작이 같은데, 순서를 보장한다.

cf) interleaving in WebFlux
webflux에서는 데이터 흐름에서 다른 데이터가 끼어드는 것을 인터리빙이라고 한다.




doOnNext와 doOnSuccess의 차이

doOnNext : 데이터가 성공적으로 '방출'되었을 때 실행됨 (즉 데이터가 empty이면 안되고 존재해야함)
doOnSuccess : 앞의 publisher가 성공적으로 '완료'되었을 때 실행됨 (즉 데이터가 empty여도 됨)

-> 한편 둘 다 error인 상황에서는 실행되지 않음.
-> 둘 다 스트림에 영향을 끼치지 않음(일반적으로 log 같은 것에 사용). 즉 여기서 반환된 값은 다음 스트림으로 전달되지 않음(이전 스트림의 값이 다음 스트림으로 전달됨)


Mono.error(new RuntimeException("Something wrong"))
    .doOnNext(i -> System.out.println("On next: " + i))
    .doOnSuccess(i -> System.out.println("On success: " + i))
    .doOnError(i -> System.out.println("On error: " + i))
    .block();
    
On error: java.lang.RuntimeException: Something wrong

참고

then

then도 doOnSuccess와 마찬가지로 앞의 publisher가 성공적으로 '완료'되었을 때 실행됨(empty여도 괜찮음)
그런데 앞의 두 operator(doOnNext, doOnSuccess)와 달리 기존 스트림의 값을 바꿀수는 있지만, 이전 스트림의 값을 전달받지는 않는다.

updateIfRequired.then(testService.doSomething(a))
                .then(testRepository.saveSomething(a));

이전 스트림의 값을 전달받아 쓰고 싶다면 flatMap이나 map을 쓸 수 있지만, 이 경우는 empty 상황에서 스트림이 complete 되고 이후 작업은 cancel된다.

profile
📝 dev wiki

0개의 댓글