이번 글에서는 Operator 에 대해 알아보려고 합니다. Operator는 Observable 에서 받은 이벤트들을 변환하고 처리할 수 있게 만들어 줍니다.
가볍게 Operator가 무엇인지 살펴보면서 시작해봅시다.
Operator 란 ?
Operator는 Rx의 기본 요소입니다. Operator를 사용해 Observable에 의해 방출되는 이벤트를 변환하고 처리하여 대응할 수 있습니다.
Operator는 크게 아래의 세 그룹으로 나뉩니다
- Filtering Operator
- Transforming Operator
- Combining Operator
1. Filtering Operators
Filtering Operator 를 통해 .next
이벤트를 통해 받아오는 값을 선택적으로 취할 수 있습니다.
.filter
조건식에 부합하는 이벤트만 방출합니다.
.skip
- n개의 이벤트를 skip 합니다.
.skipWhile
- 조건식을 만족할 때까지 skip하고 종료합니다.
.take
- n개의 이벤트만 방출하고 complete 합니다.
.takeWhile
- skipWhile 과 유사합니다.
.distinctUntilChanged
- 연달아 같은 값이 이어질 때 중복된 값을 막아줍니다
distinctUntilChanged(:)
는 비교 로직을 커스텀할 수 있습니다.
.throttle(:_scheduler)
- 특정시간동안 발생한 이벤트 중 가장 최신의 이벤트를 방출합니다
- Tap을 여러번 했을 때 최신의 이벤트만 방출되는 것을 볼 수 있습니다.
2. Transforming Operators
Observable을 변형하는 Operator 입니다.
.map()
- 이벤트를 다른 이벤트로 변형합니다.
- Observable에서 작동된다는 점을 제외하면 Swift 표준의
map
과 같습니다.
.flatMap()
- 이벤트 시퀀스를 다른 이벤트 시퀀스로 변형합니다.
- Observable sequence의 각 요소를 Observable sequence에 투영하고 Observable sequence를 Observable sequence로 병합합니다.
- 쉽게 말하면 Observable의 이벤트를 받아 새로운 Observable로 변환합니다.
.flatMapLatest()
- flatMap 에서 가장 최신의 값만을 확인하고 싶을 때 사용합니다
- flatMap과 동일하게 이벤트가 들어오면 새로운 Observable을 만듭니다. 하지만 새 Observable을 생성하면 자동적으로 이전의 Observable 구독을 해지합니다.
.flatMapFirst()
flatMapFirst
는 flatMapLatest와 반대로 이전에 생성한 Observable의 동작이 다 끝날 때까지 새로 생성한 Observable은 무시합니다.
3. Combining Operators
Sequence들을 모으고, 각 Sequence 내의 데이터를 병합하는 Operator 입니다.
.concat(_:)
- 여러 Sequence를 순서대로 묶어줍니다.
- 첫 번째 Sequence가 완료될 때까지 구독하고 다음 Sequence를 같은 방법으로 구독합니다.
- Observable.concat(_:)과 달리 .concat(_:)은 요소들이 같은 타입일 때 가능합니다.
.merge()
- Sequence를 합치는 가장 쉬운 방법입니다.
- 여러 Observable에 공통된 로직을 실행해야 할 때 merge 해서 Subscribe 할 수 있습니다.
.combineLatest()
- 여러 Observable에서 가장 최신의 값을 병합하여 방출합니다.
- 모든 Observable이 하나의 값을 방출하는 순간까지 아무일도 일어나지 않습니다.
- 한 번 값을 방출한 이후에는 클로저가 각각의 Observable이 방출하는 최신의 값을 받습니다.
.zip()
- 발생 순서가 같은 Event 끼리 병합하여 방출합니다.
- 이벤트끼리 쌍을 이루지 않으면 방출하지 않습니다.
.withLatestFrom(_:)
- 한쪽 Observable의 이벤트가 발생할 때 두개의 Observable을 병합해줍니다.
- 아래 예제에서는 Observabl<Int>의 이벤트가 발생할 때 Observable<String>과 병합하고 있습니다.
.scan()
- 값을 저장해 가지고 있을 수 있고, 그 값을 통해 이벤트를 변형할 수 있습니다.
- 변형하는 이벤트의 타입은 원본 이벤트 타입과 같아야 합니다.
- 초기값을 지정해야 합니다.
Example
위에서 다룬 Operator 들을 활용한 예제를 살펴봅시다.
- filter를 사용해 text가 nil이 아닐 경우만 가져옵니다.
- throttle을 사용해 0.5초 동안 발생한 가장 최신 이벤트를 사용합니다.
- text를 SearchRequest로 변환합니다.
이런 식으로 흐름 중에서 데이터를 가공하여 뷰에 반영할 수 있습니다.