1

이 코드를 반응 스타일로 리팩토링 할 수 있습니까?Refactor ReactiveCrudRepository.deleteAll(). 블록 (비 차단 코드)

userService.deleteAll().then().block(); 
userService.saveAll(Flux.just(candidate, tech, pm, hr)).then().block(); 

나는이 구현은 onNext(…)then(…)의 방법으로 간단하게 할 수 있다고 생각합니다. 고마워요. (이 경우에 Mono입니다) 결과 Publisher 구독

Mono<Void> mono = userService.deleteAll() 
      .thenMany(userService.saveAll(Flux.just(candidate, tech, pm, hr))) 
      .then(); 

을 찾고 실행을 시작하는 자연적인 방법이처럼

+0

'then(). block()'대신'.subscribe()'를 사용하십시오. –

+0

@ M.Deinum 왜 그런지 설명해 주시겠습니까? – maystrovyy

+0

왜냐하면'block'there는 당신의 코드에 대해 아무 반응이 없기 때문에 블로킹이됩니다 ... –

답변

3

는 것 같습니다.

반응 순서를 설정 한 후 실행 방법을 고려해야 할 때입니다. 시퀀스를 구독하는 것은 자연 접근 (.subscribe())으로 실행을 시작하지만, 그렇게 할 이유가 없다면 대개 자신이 작성한 코드에서 수행하는 것이 아닙니다. 소스 Publisher (귀하의 경우에는 MongoDB/Couchbase/Cassandra 드라이버 중 하나임)에 따라, 서브 스크립 션은 .subscribe()에 대한 호출이 완료된 후에도 계속 실행되는 비 블로킹 프로세스를 시작합니다. 일반적으로 인프라 (컨테이너)는 구독을 트리거하고 동기화를 처리합니다 (.subscribe(Subscription) 통해). 서버 응답의 일부로 Mono<Void>에 전달하여

@PostMapping("…") 
public Mono<Void> save() { 

    Mono<Void> mono = userService.deleteAll() 
      .thenMany(userService.saveAll(Flux.just(candidate, tech, pm, hr))) 
      .then(); 

    return mono; 
} 

, 당신은 실행에 대한 반응 순서를 넘겨 : 같은 봄 WebFlux 컨트롤러의 맥락에서 코드를 볼 수 있었다. 기본 컨테이너는 Publisher에 가입하고 가입이 종료되면 곧바로 HTTP 응답을 작성합니다 (동기화 부분).

반응 순서를 직접 실행하려면 직접 동기화를 처리해야합니다. Mono.block()/Flux.block()은 격리 된 환경에서 통화를 동기화하는 편리한 방법이지만 아주 좋은 이유 이외에는 할 일이 아닙니다. 아주 좋은 이유는 주변 컨테이너가없고 코드가 대규모로 실행되지 않는다는 것입니다. 블로킹 호출을 사용하면 실행이 종료 될 때까지 스레드가 차단되기 때문에 리액션 실행 모델이 제공하는 이점을 잃을 수 있습니다.

마지막 단어가 .deleteAll() 인 경우 : 데이터를 제거하거나 삽입하여 구성 요소 또는 데이터베이스 상태를 초기화해야하는 경우가 있습니다. 이 모든 초기화 프로그램은 동기식 API (Spring의 afterPropertiesSet(), JSR 250 's @PostConstruct) 내에서 실행됩니다. 이 특정 상황에서, 당신은 보통 명령형 API를 고집합니다. 대개 동기화를 직접 처리하기를 원하지 않기 때문입니다.