Combining Operator 의 종류
startWith
- Observable 시퀀스 앞에 새로운 초기값을 추가함.
var disposeBag = DisposeBag()
let classRoom = Observable.of("student1","student2","student3")
classRoom
.starWith("teacher")
.subscribe(onNext: {
print($0)
})
.disposed(by: disposeBag)
// teacher
// student1
// student2
// student3
concat
- 같은 데이터 타입의 요소를 갖는 두개의 Observable들을 묶을 때 사용함.
var disposeBag = DisposeBag()
let first = Observable.of(1, 2, 3)
let second = Observable.of(4, 5, 6)
Observable
.concat([first, second])
.subscribe(onNext: { value in
print(value)
})
.disposed(by: disposeBag)
// 1
// 2
// 3
// 4
// 5
// 6
first
.concat(second)
.subscribe(onNext: { value in
print(value)
})
.disposed(by: disposeBag)
// 1
// 2
// 3
// 4
// 5
// 6
concatMap
- 각각의 시퀀스가 다음 스퀀스가 구독되기 전에 합쳐짐을 보증함.
- 즉, flatMap 같은 경우 각각의 시퀀스는 파이프라인 병행식으로 진행하는 반면,
- concatMap은 시퀀스 순서대로 직렬로 합쳐짐을 보증해줌.
let sequences = [
"room1": Observable.of("student1", "student2", "student3"),
"room2": Observable.of("student4", "student5", "student6")
]
var disposeBag = DisposeBag()
let observable = Observable.of("room1", "room2")
observable
.flatMap { room in
sequences[room] ?? .empty()
}
.subscribe({
print($0.element ?? "")
})
.disposed(by: disposeBag)
// room1 구독
// student1
// student2
// room2 구독
// student4 <- 엇갈리면서 순서 보장이 안됨.
// student3
// student5
// student6
observable
.concatMap { room in
sequences[room] ?? .empty()
}
.subscribe({
print($0.element ?? "")
})
.disposed(by: disposeBag)
// room1 구독
// student1
// student2
// student3 <- room1 seq가 완전히 끝난 후 room2 seq 진행
// room2 구독
// student4
// student5
// student6
merge
- sequence들을 합치는 방법 중 하나
- merge하고 있는 여러 시퀀스들을 동시에 구독하면서 먼저 오는 이벤트들을 바로 방출함. (선착순)
- 최대 몇 개까지의 시퀀스를 합칠 것인지 정할 수 있음.
- 내부 시퀀스가 종료되면 merge 시퀀스도 종료됨.
- 내부 시퀀스가 complete되는 시점은 모두 독립적.
- 만약 내부 시퀀스에서 error가 방출하면 merge 시퀀스도 에러를 방출시키면 종료됨.
var disposeBag = DisposeBag()
let left = PublishSubject()
let right = PublishSubject()
let source = Observable.of(left.asObservable(), right.asObservable())
let observable = source.merge()
observable
.subscribe(onNext: {
print($0)
})
.disposed(by: disposeBag)
left.onNext(1)
right.onNext(4)
right.onNext(5)
left.onNext(2)
right.onNext(6)
left.onNext(3)
// 1
// 4
// 5
// 2
// 6
// 3
combineLatest
- 두 개의 시퀀스를 하나의 시퀀스로 합침.
- 서브 시퀀스에서 이벤트가 방출할 때 마다 이벤트를 방출함.
- 서브 이벤트에서 최초 이벤트가 방출해야지만 합쳐진 시퀀스에서 이벤트가 방출함.
var disposeBag = DisposeBag()
let left = PublishSubject()
let right = PublishSubject()
let observable = Observable
.combineLatest(left, right,
resultSelector: { lastLeft, lastRight in
"(lastLeft), (lastRight)"
})
.disposed(by: disposeBag)
let disposable = observable
.subscribe(onNext: { value in
print(value)
})
.disposed(by: disposeBag)
left.onNext(1)
right.onNext(4)
right.onNext(5)
left.onNext(2)
right.onNext(6)
left.onNext(3)
// 1, 4
// 1, 5
// 2, 5
// 2, 6
// 3, 6
zip
- 결합을 원하는 각각의 시퀀스들의 요소들을 순차적으로 결합함.
- 둘중 하나의 Observable이 완료되면 zip에대한 Observable은 종료함.
- 두 개 이상의 Observable에서 방출된 순서가 같은 아이템을 묶어서 하나의 아이템으로 방출함.
let disposeBag = DisposeBag()
let numSubject = PublishSubject<Int>()
let charSubject = PublishSubject<String>()
let zippedObservable = Observable.zip(numSubject, charSubject)
zippedObservable
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
numSubject.onNext(1)
charSubject.onNext("A")
numSubject.onNext(2)
charSubject.onNext("B")
charSubject.onNext("C")
charSubject.onNext("D")
numSubject.onNext(3)
numSubject.onNext(4)
numSubject.onNext(5)
// 1A
// 2B
// 3C
// 4D
// 5는 결합하지 못한상태로 방출되지못함.
combineLatest과 zip의 비교
withLatestFrom
- withLatestFrom을 호출한 Observable은 onNext하면 withLatestFrom의 파라미터인 Observable의 최신값을 trigger함.
- 특정 트리거가 방출 됐을 때 특정 상태의 최신 값을 얻고 싶을 때 사용
var disposeBag = DisposeBag()
let button = PublishSubject<Void>()
let textField = PublishSubject<String>()
button
.withLatestFrom(textField)
.subscribe(onNext: {
print($0)
})
.disposed(by: disposeBag)
textField.onNext("par")
textField.onNext("pari")
textField.onNext("paris")
button.onNext(Void())
button.onNext(Void())
// paris
// paris
sample
- withLatestFrom 처럼 trigger 역할을 하지만 단 한번만 trigger함
- withLastFrom과 비슷하게 sample이 있는데 이것은 중복된 값이 들어올 경우 이벤트는 한번만 방출된다
var disposeBag = DisposeBag()
let button = PublishSubject<Void>()
let textField = PublishSubject<String>()
button
.sample(textField)
.subscribe(onNext: {
print($0)
})
.disposed(by: disposeBag)
textField.onNext("par")
textField.onNext("pari")
textField.onNext("paris")
button.onNext(Void())
button.onNext(Void())
// paris
그 외 Combining Operator
- reduce
- scan
- switchLatest
- amb
- .... 등등
'rxSwift' 카테고리의 다른 글
[rxSwift] TimeBased Operator 의 종류 (0) | 2022.10.29 |
---|---|
[rxSwift] Transforming Operator 의 종류 (0) | 2022.10.23 |
[rxSwift] Filtering Operator 의 종류 (0) | 2022.10.22 |
[rxSwift] Subject 를 wrapping한 Relay 사용법 (0) | 2022.10.21 |
[rxSwift] Subject 에 대한 이해와 종류 (0) | 2022.10.21 |