Operator는 Observable에서 받은 이벤트들을 변환하고 처리할 수 있도록 해준다.
1, 2, 3이라는 세 가지 값을 가지고 있는 시퀀스가 있다고 해보자. ignoreElements()
라는 ignoring operator를 사용하면 시퀀스의 모든 원소들을 무시한다. 그런데 이때도 completed 이벤트는 발생하게 된다.
let strikes = PublishSubject<String>()
let disposeBag = DisposeBag()
strikes
.ignoreElements()
.subscribe { _ in
print("[Subscription is called]")
}.disposed(by: disposeBag)
strikes.onNext("A")
strikes.onNext("B")
strikes.onNext("C")
위 코드를 실행해보면 아무 것도 출력되지 않는다. ignoreElements()
라는 operator를 실행했기 때문!
이 subscription은 onCompleted
라는 completed 이벤트가 발생했을 때만 호출된다.
strikes.onCompleted()
위 코드를 추가해주면 [Subscription is called]
라는 문구가 잘 출력된다.
Ignoring Operator는 실제 값은 상관없고 observation이 완료되었는지만 구독받고 싶을 때 사용하면 좋다.
어떤 시퀀스가 있을 때 elementAt()
메소드를 사용하면 인자로 전달된 인덱스에 있는 값을 얻을 수 있다.
let strikes = PublishSubject<String>()
let disposeBag = DisposeBag()
strikes.element(at: 2)
.subscribe(onNext: { _ in
print("You are out!")
}).disposed(by: disposeBag)
strikes.onNext("X")
strikes.onNext("X")
strikes.onNext("X") // You are out!
strikes
에서 elementAt()
메소드를 호출하고 구독했다. 이후 세 번째 값이 방출되었을 때 이벤트가 실행이 된다. 두 번째 값까지만 방출하면 이벤트는 실행되지 않는다.
조건에 맞는 값만 방출하는 operator이다.
let strikes = PublishSubject<String>()
let disposeBag = DisposeBag()
Observable.of(1, 2, 3, 4, 5, 6, 7)
.filter { $0 % 2 == 0 }
.subscribe(onNext: {
print($0)
}).disposed(by: disposeBag)
// 출력 결과
// 2
// 4
// 6
위 Observable에서 filter()
메소드를 호출하여 짝수 값이 방출될 때만 이벤트가 호출되는 것을 볼 수 있다.
파라미터로 받은 숫자만큼 방출된 항목들을 건너뛰는 operator이다.
let strikes = PublishSubject<String>()
let disposeBag = DisposeBag()
Observable.of("A", "B", "C", "D", "E", "F")
.skip(3)
.subscribe(onNext: {
print($0)
}).disposed(by: disposeBag)
// 실행 결과
// D
// E
// F
조건식을 만족할 때까지 계속 건너뛴다. 한 번 조건식이 false
가 되면 이후 다른 값들은 모두 시퀀스의 항목에 포함된다.
let strikes = PublishSubject<String>()
let disposeBag = DisposeBag()
Observable.of(2, 2, 3, 4, 4)
.skip(while: { $0 % 2 == 0 })
.subscribe(onNext: {
print($0)
}).disposed(by: disposeBag)
/* 실행 결과:
3
4
4
*/
트리거 역할을 하는 Operator가 이벤트를 방출하기 전까지 항목을 건너뛴다.
다른 observable을 기반으로 하기 때문에 동적으로 요소들을 필터링 할 수 있다는 장점이 있다!
let strikes = PublishSubject<String>()
let disposeBag = DisposeBag()
let subject = PublishSubject<String>()
let trigger = PublishSubject<String>()
subject.skip(until: trigger)
.subscribe(onNext: {
print($0)
}).disposed(by: disposeBag)
subject.onNext("A")
subject.onNext("B")
trigger.onNext("X")
subject.onNext("C")
/* 실행 결과
C
*/
trigger
가 항목을 방출한 후에야 subject
의 C라는 항목이 방출된 것을 볼 수 있다.
Skip Operator와 유사하지만 정반대로 동작하는 operator이다.
처음부터 n개의 항목들만 방출한다.
let strikes = PublishSubject<String>()
let disposeBag = DisposeBag()
Observable.of(1, 2, 3, 4, 5, 6)
.take(3)
.subscribe(onNext: {
print($0)
}).disposed(by: disposeBag)
/* 실행 결과:
1
2
3
*/
조건식을 만족하는 동안 항목들을 방출한다. 조건식이 false
가 되면 더 이상 방출을 하지 않는다.
let strikes = PublishSubject<String>()
let disposeBag = DisposeBag()
Observable.of(2, 4, 6, 7, 8, 10)
.take(while: {
$0 % 2 == 0
}).subscribe(onNext: {
print($0)
}).disposed(by: disposeBag)
/* 실행 결과:
2
4
6
*/
트리거 역할을 하는 observable이 항목을 방출하거나 종료되기 전까지 항목들을 방출한다.
let strikes = PublishSubject<String>()
let disposeBag = DisposeBag()
let subject = PublishSubject<String>()
let trigger = PublishSubject<String>()
subject.take(until: trigger)
.subscribe(onNext: {
print($0)
}).disposed(by: disposeBag)
subject.onNext("1")
subject.onNext("2")
trigger.onNext("X")
subject.onNext("3")
/* 실행 결과:
1
2
*/
trigger
가 X라는 항목을 방출하기 전까지만 subject
의 항목이 출력되는 것을 볼 수 있다.