switchMap을 사용하여 여러 조건부 요청을 처리하는 방법은?
_____Q1: switchMap이란 무엇인가요?
A1: switchMap은 RxJS의 연산자로, 내부 옵저버블을 생성하는 함수에 소스 옵저버블의 각 값을 매핑하며, 새로운 내부 옵저버블이 방출되면 이전 내부 옵저버블 구독을 자동으로 취소(switch)합니다. 이를 통해 최신 요청만 처리하고 이전 요청은 무시할 때 유용합니다.
Q2: 여러 조건부 요청이란 무엇인가요?
A2: 여러 조건부 요청이란, 특정 조건이나 입력값에 따라 서로 다른 API 요청이나 비동기 작업을 수행하는 것을 의미합니다. 예를 들어, 입력 폼 값에 따라 다른 엔드포인트를 호출하거나, 특정 상태에 따라 분기되는 요청을 말합니다.
Q3: switchMap으로 조건에 따른 요청을 어떻게 처리하나요?
A3: switchMap 안에서 조건문(if/else or switch)를 사용하여 조건에 맞는 Observable을 반환합니다. 즉, 소스값에 따라 서로 다른 요청 Observable을 리턴하여 조건별 API 호출을 할 수 있습니다.
```typescript
source$.pipe(
switchMap(value => {
if (value === 'A') {
return http.get('/api/pathA');
} else if (value === 'B') {
return http.get('/api/pathB');
} else {
return of(null); // 조건에 맞지 않는 경우 빈 Observable 반환
}
})
).subscribe(result => console.log(result));
```
Q4: 왜 switchMap을 쓰는 것이 좋은가요?
Q5: 조건이 많을 경우 코드가 복잡해질 수 있는데 어떻게 관리하나요?
A5: 조건별 요청을 별도 함수로 분리하거나, 조건-요청 매핑 객체(맵)를 만들어 사용하는 방법이 있습니다. 예를 들어:
```typescript
const requestMap = {
A: () => http.get('/api/pathA'),
B: () => http.get('/api/pathB'),
C: () => http.get('/api/pathC'),
};
source$.pipe(
switchMap(value => requestMap[value]?.() ?? of(null))
);
```
Q6: 요청 취소가 정상적으로 되는지 확인하려면 어떻게 하나요?
A6: switchMap은 자동으로 이전 내부 옵저버블 구독을 해제하므로, 요청 취소가 필요한 HTTP 클라이언트(httpClient 등)는 요청 취소 토큰을 지원해야 합니다. Angular의 HttpClient 등은 이를 기본으로 지원합니다.
Q7: switchMap 대신 다른 연산자를 써도 되나요?
A7: 조건별 요청에서 이전 요청 취소가 필요하지 않거나 결과를 모두 처리해야 한다면 mergeMap, concatMap 등을 사용할 수 있습니다. 하지만 최신값만 필요하고 이전 요청은 무시해야 할 때 switchMap이 적합합니다.
---
요약: switchMap 내부에서 조건문으로 여러 요청 Observable을 분기 처리하고, 최신 요청만 구독하도록 하여, 사용자의 입력이나 상태 변화에 따라 동적이고 효율적인 비동기 요청 관리를 구현할 수 있습니다.
--- 기본 개념 `switchMap`은 RxJS에서 가장 많이 사용하는 고차 연산자 중 하나입니다.
내부에서 새로운 Observable을 반환하는 함수를 받아서, 원본 Observable이 새로운 값을 방출할 때마다 기존에 구독하고 있던 내부 Observable을 취소하고, 최신 값으로부터 생성된 Observable을 구독하는 역할을 합니다.
이 특성 때문에, 여러 조건에 따라 서로 다른 HTTP 요청이나 비동기 작업을 처리할 때 매우 유용합니다.
예를 들어, 사용자의 입력 변화에 따라 적절한 API를 호출하거나, 특정 조건에 따라 다양한 요청을 동적으로 처리할 수 있습니다.
--- 여러 조건부 요청 처리하기 가장 일반적인 패턴은 원본 Observable(예: UI 입력값, 특정 이벤트)으로부터 들어오는 값에 따라, 조건문을 활용해 서로 다른 Observable들을 반환하는 것입니다.
예를 들어, 다음과 같은 시나리오를 고려해 봅시다: - 입력 값이 빈 문자열이면, 빈 배열을 반환하는 비동기 요청을 수행한다(예: 서버 호출 없이 빈 결과 반환). - 입력 값이 특정 문자열 패턴에 부합하면, A API를 호출한다.
- 그 밖의 경우에는 B API를 호출한다.
--- 구현 예시 ```typescript import { of, EMPTY } from 'rxjs'; import { switchMap } from 'rxjs/operators'; inputObservable.pipe( switchMap(value => { if (!value) { // 값이 없으면 빈 배열 반환 (HTTP 요청 없이) return of([]); } else if (/patternA/.test(value)) { // 특정 패턴을 만족하면 A API 호출 return apiService.getA(value); } else { // 그 외에는 B API 호출 return apiService.getB(value); } }) ).subscribe(result => { // result 는 항상 배열 형태일 것으로 예상 console.log(result); }); ``` - `inputObservable`은 사용자의 입력이나 어떤 이벤트를 나타낸다. - `switchMap` 내부에서 조건부 분기문으로 어떤 Observable을 반환할지 결정한다.
- 각 분기에서 반환하는 Observable은 모두 같은 타입(예를 들어 배열)을 반환한다는 점이 중요하다. - `switchMap`은 새로운 값으로 전환될 때 기존에 구독 중이던 API 호출을 취소하기 때문에, 네트워크 호출이 중복되는 에러를 줄이는 데 유용하다. --- 주의점 및 팁 1. 반환 Observable 타입 통일 : 모든 조건문이 반환하는 Observable이 비슷한 데이터 타입을 반환하도록 설계해야 구독자 쪽에서 처리하기 쉽다. 예를 들어 일부 조건은 HTTP 요청, 다른 조건은 `of([])`처럼 즉시 끝나는 Observable을 반환해도 괜찮다.
2. 에러 처리 : HTTP 요청 중 발생할 수 있는 에러를 적절히 처리해야 한다.
`catchError`를 적절히 사용해 특정 요청 실패 시에도 전체 스트림이 종료되지 않도록 설계한다.
3. 조건 분기 복잡도 관리 : 조건이 많거나 복잡할 경우, 조건 분기 로직을 별도의 함수로 분리하여 가독성을 유지하는 것이 좋다.
4. 취소 효과 : `switchMap`은 새로운 값이 들어오면 기존에 실행하던 내부 Observable을 자동으로 취소(unsubscribe) 한다는 점 때문에, 여러 빠른 입력 변화에 대해 네트워크 부하를 줄일 수 있다.
--- 정리 `switchMap`을 활용해 여러 조건부 요청을 처리하려면, `switchMap` 내부 콜백 함수 안에서 조건문을 활용하여 상황에 맞는 Observable을 반환하면 된다. 이때 반환하는 Observable은 HTTP 요청뿐 아니라, 바로 값을 반환하는 Observable(`of()`, `EMPTY`) 등도 될 수 있다.
`switchMap`의 기존 구독 취소 특성 덕분에, 빠르게 바뀌는 입력값이나 여러 조건에 따른 요청 로직을 깔끔하고 효율적으로 다룰 수 있다.
--- 필요하다면 더 구체적인 예제나 상황에 맞춘 코딩 패턴에 대해서도 추가 설명해 드릴 수 있습니다.
작성자:
정수민 [비회원]
| 작성일자: 1년 전
2025-05-25 12:51:43
조회수: 151 | 댓글: 0 | 좋아요: 0 | 싫어요: 0
조회수: 151 | 댓글: 0 | 좋아요: 0 | 싫어요: 0
내용이 부정확하다면 싫어요를 클릭해주세요.