Reactor에서 예외를 설정하는 올바른 방법
저는 Reactor와 리액티브 프로그래밍을 처음 해보는 사람입니다.
현재 다음과 같은 코드를 만들고 있습니다.
Mono.just(userId)
.map(repo::findById)
.map(user-> {
if(user == null){
throw new UserNotFoundException();
}
return user;
})
// ... other mappings
이 예는 아마 우습고 이 케이스를 구현하는 더 나은 방법이 있을 것입니다만, 요점은 다음과 같습니다.
를 사용하는 것이 잘못되었습니까?throw new의 map을 「」로 인가.return Mono.error(new UserNotFoundException())
이 두 가지 방법에 실제 차이가 있나요?
예외 발생을 방지하는 편리한 방법으로는 다음과 같은 몇 가지 방법이 있습니다.
를 조작하려면 , 「」를 사용합니다.Flux/Mono.handle
빈이 있는 할 수 중 는 연산자 「」입니다.handle.
다음 코드는 문제를 해결하기 위해 이 코드를 사용하는 방법을 보여 줍니다.
Mono.just(userId)
.map(repo::findById)
.handle((user, sink) -> {
if(!isValid(user)){
sink.error(new InvalidUserException());
} else if (isSendable(user))
sink.next(user);
}
else {
//just ignore element
}
})
.handle해야 .BiConsumer<T, SynchronousSink<>요소를 처리하기 위해.BiConsumer(바이컨슈머) 번째 이며, 두 번째 는 업스트림의 요소입니다.SynchronousSink다운스트림에 동기적으로 요소를 공급하는 데 도움이 됩니다.이러한 기술은 요소 처리의 다른 결과를 제공할 수 있는 능력을 확장합니다.들어 요소가 않은 경우 할 수 .SycnchronousSync되고 '''가 생성됩니다.onError하다'필터링'을 할 수 있어요.handle손잡이만 BiConsumer실행되며 요소가 제공되지 않습니다.Reactor는 이를 필터링의 종류로 간주하여 추가 요소를 요구합니다., '만일', '만일', '만일', '만일', '만일'이라고 부르면 됩니다.SynchronousSink#next ' 정도 맵핑'이 됩니다.handle처 map오퍼레이터입니다.또한 성능 저하 없이 해당 오퍼레이터를 안전하게 사용할 수 있으며 요소의 검증이나 다운스트림으로의 에러 송신 등 복잡한 요소 검증을 제공할 수 있습니다.
를 사용해서 던집니다.#concatMap+Mono.error
중에 중 는 맵핑에서 예외를 발생시킬 수 옵션 중 하나는 맵핑에서 예외를 발생시키는 입니다.mapconcatMap그 본질은concatMap 일을 하다flatMap이 있다면, 그 차이점이 요. 유일한 차이점은concatMap는 한번에 1개의 서브스트림만 허용합니다.이러한 동작은 내부 구현을 크게 간소화하고 성능에 영향을 주지 않습니다.따라서 다음 코드를 사용하여 보다 기능적인 방법으로 예외를 발생시킬 수 있습니다.
Mono.just(userId)
.map(repo::findById)
.concatMap(user-> {
if(!isValid(user)){
return Mono.error(new InvalidUserException());
}
return Mono.just(user);
})
사용자의 .Mono.error로 플럭스에도 할 수 Flux.error:
Flux.just(userId1, userId2, userId3)
.map(repo::findById)
.concatMap(user-> {
if(!isValid(user)){
return Flux.error(new InvalidUserException());
}
return Mono.just(user);
})
두 경우 모두 하나의 요소만 있는 콜드 스트림을 반환합니다.Reactor에서는 반환되는 스트림이 콜드 스칼라 스트림인 경우 성능을 향상시키는 몇 가지 최적화가 있습니다.따라서 Flux/Mono 사용을 권장합니다.concatMap+.just,empty,error 복잡한 매핑이 때, 그, 보, 보, 과로 끝날 수 .return null ★★★★★★★★★★★★★★★★★」throw new ....
주목! 들어오는 요소를 절대 확인하지 마십시오. Reactive Streams 사양(규칙 2.13 참조)에 위반되기 때문에 Reactor Project는 값을 송신하지 않습니다.따라서 다음과 같은 경우
repo.findById.Reactor(리액터) 늘 포인터외입니니다다
왜 wait, ??concatMap보다 flatMap
,본 in in in in inflatMap는 동시에 실행되는 여러 서브스트림의 요소를 결합하도록 설계되어 있습니다., 그에 비동기 이 있어야 여러 상의 를 처리할 도 있고 콜이 도 있습니다.후, 에 큰 을 미치기 때문에, 이러한 기대는 이행에 큰 영향을 미칩니다.flatMap의 스트림으로부터의 할 수 필요가 (이러한 경우).Thread ( 데이터의 사용 예), 다른의 추가 예), 요소(의 추가 메모리 할당 예), enqueue 요소.Queue각 서브스트림에 대해 s) 및 Reactive Streams 사양 규칙을 위반하지 않아야 합니다(실장이 매우 복잡함을 의미합니다). map(를 사용하여 조작Flux/Mono.error하지 않음)에 따라 훨씬 더 (실행 동기성) 연산자를 할 수 .concatMap이는 한 번에 단일 스트림의 비동기 처리를 위해 설계되었으며 스칼라 콜드 스트림을 처리하기 위해 몇 가지 최적화 기능을 갖추고 있습니다.
사용하여 를 발생시킵니다.switchIfEmpty
결과가 있을 때 또 은 '비우다'입니다.switchIfEmpty이 에서는 어떻게하면 좋은지 알 수 .
Mono.just(userId)
.flatMap(repo::findById)
.switchIfEmpty(Mono.error(new UserNotFoundExeception()))
이 repo::findById 한다MonoUser반환 유형으로 지정됩니다.'의 User인스턴스를 찾을 수 없습니다. 이치노Reactor는 Reactor를 합니다.Mono )로 지정됩니다.switchIfEmpty파라미터를 지정합니다.
있는 (의 예:map,filter★★★★★★★★★★★★★★★★★★★★★★★」
읽기 어려운 코드 또는 잘못된 관행(내 의견)으로 간주될 수 있지만, 예외는 그대로 둘 수 있습니다(예:.map(v -> throw ...)프로젝트 리액터 포함.어떤 면에서는 이렇게 하면 Reactive Streams 사양을 위반할 수 있습니다(이 문맥에서는 후드 아래의 연산자는SubscriberSubscriber - 은 s에 수 .onNext(스펙 규칙 2.13)을 위반하는 메서드).단, Reactor는 투척된 예외를 검출하여 그 예외를 전파합니다.onError다운스트림에 신호를 보내는 것은 금지되지 않습니다.
테이크 아웃
.handle요소concatMap+Mono.error매핑 중에 예외를 발생시킬 필요가 있지만 이러한 기술은 비동기 요소 처리의 경우에 가장 적합합니다.flatMap+Mono.error먹었을 때flatMapNull되어 있기 에, 「복귀 타입」이 아닌, 「 타입」이 금지되어 있습니다.nullmap의 일이onErrorNullPointerExceptionswitchIfEmpty특정 함수를 호출한 결과가 빈 스트림으로 종료된 경우 오류 신호를 전송해야 하는 모든 경우
언급URL : https://stackoverflow.com/questions/53595420/correct-way-of-throwing-exceptions-with-reactor
'source' 카테고리의 다른 글
| 여러 UTF-8 BOM 시퀀스 삭제 방법 (0) | 2022.11.05 |
|---|---|
| PHP의 숨겨진 기능 (0) | 2022.11.05 |
| 포인터 투 포인트 슛은 C에서 어떻게 작동합니까? (그리고 언제 사용할 수 있습니까?) (0) | 2022.11.05 |
| MySQL - 우편번호 앞에 "0"을 붙이는 방법 (0) | 2022.11.05 |
| 부울 필드를 인덱싱하면 성능이 향상됩니까? (0) | 2022.11.05 |