RxJS는 실시간 사용자 입력, API 호출, 비동기 처리 등을 효율적으로 제어할 수 있도록 도와주는 연산자들이 실서비스에서도 자주 활용됩니다.
1. debounceTime – 사용자 입력 지연 처리
시나리오
- 검색창에서 사용자가 입력을 마칠 때까지 대기 후 API 호출
- 과도한 이벤트 트리거 방지 (ex: 스크롤, 키보드 입력 등)
예제: 검색어 자동완성
searchControl = new FormControl();
ngOnInit() {
this.searchControl.valueChanges
.pipe(
debounceTime(300), // 300ms 동안 입력 없을 때만 다음으로
distinctUntilChanged(), // 중복 입력 무시
switchMap(keyword => this.searchService.search(keyword))
)
.subscribe(result => {
this.searchResult = result;
});
}
- debounceTime은 과도한 API 요청을 막고 사용자 경험(UX)을 향상시키는 핵심 연산자입니다.
2. switchMap – 이전 요청 무시 & 최신 요청만 반영
시나리오
- 검색, 자동완성 등 빠르게 요청이 연속적으로 들어올 때
- 이전 요청이 완료되기 전에 새로운 요청이 오면 이전 것은 무시
예제: 실시간 유저 검색
this.userSearchControl.valueChanges
.pipe(
debounceTime(300),
switchMap(query => this.userService.findUsers(query)) // 이전 요청은 취소됨
)
.subscribe(users => {
this.foundUsers = users;
});
- switchMap은 "가장 최근의 요청만 유효" 해야 할 때 이상적입니다.
- 로그인 중복 확인, 주소 검색 등에 유용하게 사용됩니다.
3. mergeMap – 여러 요청 병렬 처리 (순서 무관)
시나리오
- 체크된 여러 항목에 대해 각각 API 호출
- 순서 상관없이 병렬로 처리하고 결과 모두 받기
예제: 다중 유저 초대 처리
from(this.selectedUserIds)
.pipe(
mergeMap(userId => this.inviteService.sendInvite(userId))
)
.subscribe({
next: result => console.log(`${result.userName} 초대 성공`),
error: err => console.error('초대 실패', err)
});
- mergeMap은 모든 요청을 동시에 병렬로 실행합니다.
- 단, 응답 순서는 보장되지 않습니다.
- 순서가 중요한 경우엔 concatMap 사용을 고려하세요.
4. exhaustMap – 버튼 연타 방지
예: 로그인 버튼을 중복 클릭하는 사용자 제어
fromEvent(this.loginButton.nativeElement, 'click')
.pipe(
exhaustMap(() => this.authService.login())
)
.subscribe({
next: () => console.log('로그인 성공'),
error: () => console.log('로그인 실패')
});
- 로그인 요청이 완료될 때까지 다른 클릭은 무시됩니다.
마무리 정리
| 연산자 | 설명 | 주요 용도 |
| debounceTime | 지정 시간만큼 이벤트 지연 | 입력 필터링, 검색 |
| switchMap | 이전 Observable 무시하고 최신으로 교체 | 검색어 자동완성, 주소 검색 등 |
| mergeMap | 모든 Observable 병렬 실행 | 다중 요청 (e.g. 파일 업로드) |
| exhaustMap | 현재 작업 중이면 무시 | 중복 요청 방지 (e.g. 로그인) |
'개발 공부 > Angular' 카테고리의 다른 글
| Angular 동적 라우팅 vs 쿼리 파라미터 (0) | 2025.06.01 |
|---|---|
| 앵귤러 동적 라우팅(Dynamic Routing) (0) | 2025.05.31 |
| 컴포넌트 인클루전 방식 vs 라우트 분리 방식 (0) | 2025.05.27 |
| Angular computed() (0) | 2025.05.26 |
| @HostListener (0) | 2025.05.19 |