RxSwift 연산자 정리:
map
, flatMap
, flatMapLatest
RxSwift에서 map
, flatMap
, flatMapLatest
는 Observable의 값을 변형하거나 흐름을 바꿀 때 사용하는 연산자. 각각의 목적과 동작 방식이 다름!!!
1. map
- 입력 값을 가공하여 다른 값으로 변환하는 연산자
Observable<T>
→Observable<U>
- 비동기 작업이 필요 없는 간단한 변형에 사용
1
2
3
4
5Observable.of(1, 2, 3)
.map { $0 * 2 }
.subscribe(onNext: { print($0) })
// 출력: 2, 4, 6
2. flatMap
- 값을 변형하여 새로운 Observable을 만들고, 그 결과를 모아서 하나의 Observable로 평탄화(flatten) 함
Observable<T>
→Observable<Observable<U>>
→Observable<U>
- 비동기 작업에서 자주 사용됨
- 모든 내부 Observable의 이벤트를 다 구독함
1
2
3
4
5
6
7
8
9
10
11
12
13
14struct User {
let name: String
func fetchProfile() -> Observable<String> {
return Observable.just("Profile of \(name)")
}
}
Observable.of(User(name: "Alice"), User(name: "Bob"))
.flatMap { $0.fetchProfile() }
.subscribe(onNext: { print($0) })
.disposed(by: self.disposeBag)
// Profile of Alice
// Profile of Bob
3. flatMapLatest
flatMap
과 유사하지만, 가장 최근에 생성된 Observable만 구독- 이전 Observable이 완료되지 않아도 무시하고 최신 것으로 바뀜
- 보통 검색, 입력, 위치 추적 등에서 많이 사용
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26let subject = PublishSubject<String>()
subject.flatMapLatest { keyword in
Observable<Int>.interval(.seconds(1), scheduler: MainScheduler.asyncInstance)
.map { "\(keyword): \($0)" }
}
.subscribe(onNext: { print($0) })
.disposed(by: self.disposeBag)
subject.onNext("A") // A로 시작된 Observable 시작
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
subject.onNext("B") // B로 변경되면 A는 중단되고 B만 계속됨
}
A: 0
A: 1
B: 0
B: 1
B: 2
B: 3
B: 4
B: 5
B: 6
B: 7
B: 8
B: 9
B: 10
차이점
연산자 | 설명 | 비동기 처리 | 이전 Observable 취소 |
---|---|---|---|
map |
값만 단순히 변환 (T → U ) |
❌ | 해당 없음 |
flatMap |
T → Observable<U> , 모든 Observable 유지 |
✅ | ❌ 유지됨 |
flatMapLatest |
T → Observable<U> , 가장 최근 것만 유지 |
✅ | ✅ 취소됨 |
사용시점
상황 | 추천 연산자 |
---|---|
단순한 값의 변환이 필요할 때 | map |
여러 비동기 작업을 동시에 허용할 때 | flatMap |
마지막 입력만 유효한 상황 | flatMapLatest |