-
Mono.zipWith 혹은 Mono.zipWhen이 호출되지 않을 때TECH/Java 2022. 10. 23. 19:43
소스 Mono가 empty이거나 Mono<Void>인 경우, 일부 조합은 절대 호출되지 않을 수 있다.
정의에 따르면 소스에서 결과물을 만들어 내기 위해 요소가 필요한 zip, zipWith, zipWhen와 같은 transformer(변환 연산자)에서 흔히 발생하는 일이다.
따라서 data-supressing 오퍼레이터를 zip에 사용하는 것은 문제가 된다.
data-supressing operators 예시
- then
- thenEmpty(Publisher<Void>)
- ignoreElements
- ignoreElement()
- when(Publisher)
설명이 잘 와닿지가 않는데, 간단하게 예시를 통해 살펴보자.
@Test void test1() { StepVerifier.create(Mono.empty() // 1 ... empty 사용 .zipWith(Mono.just("test data"))) .expectNextCount(0) .verifyComplete(); StepVerifier.create(methodReturnsMonoVoid() .zipWith(Mono.just("test data"))) .expectNextCount(0) .verifyComplete(); } public Mono<Void> methodReturnsMonoVoid() { return Mono.just("this method returns Mono<Void>") .then(); // 2 ... data supressing operator 사용 }
1의 경우 Mono의 Source가 empty 이기 때문에 zipWith가 호출되지 않는다.
2의 경우 Mono가 data supressing operator인 `then()` 을 사용하였고, 이로 인해 zipWith가 호출되지 않는다.유사하게, flatMap과 같이 동작을 변경하기 위해 Function<T, ?>를 사용하는 operator는 Function을 적용할 수 있도록 최소 하나 이상의 emit된 아이템을 필요로 한다. 이 함수를 empty (or <Void>) 시퀀스에 적용하는 것은 절대 element를 만들어내지 못한다.
StepVerifier.create(methodReturnsMonoVoid() // Mono<Void>를 리턴한다. .flatMap(unused -> new Mono<Void>() { @Override public void subscribe(CoreSubscriber<? super Void> actual) { System.out.println("this is never called."); } })) .expectNextCount(0) .verifyComplete();
Mono<Void>를 리턴했기 때문에 이어진 flatMap은 호출되지 않는다.
T 타입의 빈 시퀀스를 기본 값이나 fallback Publisher<T>로 대체하기 위해 .defaultIfEmpty(T) 그리고 .switchIfEmpty(Publisher<T>)를 사용할 수 있는데, 이는 이러한 상황을 피하도록 도와준다.
StepVerifier.create(Mono.empty() .switchIfEmpty(Mono.just("test1")) // empty 인 경우 값을 대체 .zipWith(Mono.just("test2"))) .consumeNextWith(tuple2 -> { Assertions.assertEquals(tuple2.getT1(), "test1"); Assertions.assertEquals(tuple2.getT2(), "test2"); }) .verifyComplete();
하지만 이 함수들은 Flux<Void>/Mono<Void>에 적용할 수 없다는 점에 주의하자. 여전히 empty여야 하는 다른 Publisher<Void>로 바꾸는 것만 가능하기 때문이다.
StepVerifier.create(methodReturnsMonoVoid() .switchIfEmpty(Mono.empty()) .zipWith(Mono.just("test2"))) .expectNextCount(0) .verifyComplete();
대체로 사용하는 값도 empty이기 때문에 zipWith는 호출되지 않는다.
원본 : https://projectreactor.io/docs/core/release/reference/#faq.monoThen
'TECH > Java' 카테고리의 다른 글
Singleton Pattern이란? (0) 2022.12.16 Managed Language 자바, 자바는 어떻게 힙에서 제거할 객체를 알아낼까? (0) 2022.11.29 Java String Pool이란? (0) 2022.11.17 JVM 메모리 - heap, stack (0) 2022.08.07 Slack api 호출시 account_inactive 에러가 발생하는 경우 (0) 2022.02.05