[RxSwift] Combining Operators - CombineLatest, Zip, Concat
Closed this issue · 0 comments
CombineLatest
when an item is emitted by either of two Observables, combine the latest item emitted by each Observable via a specified function and emit items based on the results of this function
→ 아이템이 두 Observable 중 어느 하나에 의해 방출되면 지정된 함수를 통해 각 Observable에서 방출된 가장 최신 아이템을 결합하고, 이 함수의 결과에 따라 아이템들을 방출합니다.
두 개의 시퀀스가 combineLatest
를 만나 하나의 시퀀스가 되었습니다.
이 합쳐진 시퀀스는 서브 시퀀스 (위에 두 개)에서 이벤트가 발생할 때마다 이벤트를 발생시킵니다.
합쳐진 시퀀스는 두 서브 시퀀스의 element를 조합하여 새로운 element를 전달합니다.
이렇게만 봐서는 어떻게 쓰이는 지 잘모르겠으니.. 예제로 봅시다!
우선 두 개의 시퀀스를 준비하고,
let left = PublishSubject<String>()
let right = PublishSubject<String>()
combineLatest
operator를 이용하여 하나로 합쳐진 시퀀스를 만들어줍니다.
let observable = Observable
.combineLatest(left, right, resultSelector: { (lastLeft, lastRight) in
"\(lastLeft) \(lastRight)"
})
let disposable = observable.subscribe(onNext: { (string) in print(string) })
이벤트를 발생 시키고, 그 값을 onNext로 받아서 프린트로 찍어볼게요!
그리고, 마지막에 dispose 해줍니다.
print("> Sending a value to Left")
left.onNext("Hello,")
print("> Sending a value to Right")
right.onNext("world")
print("> Sending another value to Right")
right.onNext("RxSwift")
print("> Sending another value to Left")
left.onNext("Have a good day,")
disposable.dispose()
결과는?? 아래와 같이 나옵니다!
- 이 예제에서는 Observable으로 같은 타입의 시퀀스를 합쳤지만, 두 개의 서브 시퀀스가 서로 다른 타입이어도 combine이 가능합니다.
-
예시코드
let disposeBag = DisposeBag() let first = Observable.of(1, 2, 3, 4) let second = Observable.of("A", "B", "C") Observable.combineLatest(first, second) .subscribe(onNext: { print("\($0)" + $1) }) .disposed(by: dispseBag) /* Prints: 1A 2A 2B 3B 3C 4C */
- 결과에서 볼 수 있듯, 두 시퀀스가 각각 최초 이벤트를 발생 시켜야만 합쳐진 시퀀스에서 이벤트가 발생합니다.
→ 두 개의 시퀀스가 최초 이벤트를 발생 시키고 난 후라면, 두 개의 시퀀스 중 어느 하나가 이벤트를 방출할 때마다 각 시퀀스의 마지막 값을 뽑아서 합쳐주니까 이메일, 비밀번호 texfield가 변할 때마다 버튼을 enabled를 체크해야 할 때 사용할 수 있을 것 같습니다!
Zip
공식 문서에 보면, CombineLatest
와 Zip
연산자는 유사한 방식으로 작동하지만 차이점이 있다고 나와있습니다.
zip에 대해서도 간단하게 알아봅시다!
combine the emissions of multiple Observables together via a specified function and emit single items for each combination based on the results of this function
→ zip 연산자는 지정된 함수를 통해 여러 Observable의 방출을 결합하고 이 함수의 결과를 기반으로 각 조합에 대해 단일 항목을 방출합니다.
combineLatest는 일단 두 시퀀스 모두에서 최초 이벤트가 발생하면, 그 이후에는 두 개의 시퀀스 중 어느 하나가 이벤트를 방출할 때마다 각 시퀀스의 마지막 값을 뽑아서 합쳐줍니다.
zip은 두 시퀀스 모두에서 항상 새로운 이벤트가 발생되어야 두 이벤트가 조합됩니다.
Concat
emit the emissions from two or more Observables without interleaving them
→ 두 개 이상의 옵저버블에서 인터리빙(= 서로 간섭)하지 않고 방출합니다.
쉽게 얘기하자면, 두 시퀀스를 합친다! 단, 순서가 보장됩니다.
Concat 연산자 는 여러 Observable의 출력을 연결하여 단일 Observable처럼 작동합니다. 첫 번째 Observable에서 내보낸 모든 항목은 두 번째 Observable에서 내보낸 항목보다 먼저 내보내집니다.
→ 동작: first subscribe 하고 complete 발생한후 second를 subscribe 합니다.
- 예시코드
let first = Observable.of(1, 2, 3)
let second = Observable.of(4, 5, 6)
// 1
Observable.concat([first, second]).subscribe(onNext: { value in print(value) })
// 2
first.concat(second).subscribe(onNext: { value in print(value) })
// 1 2 3 4 5 6
1. Observable의 class 메소드를 사용하여 시퀀스를 생성한다.
2. Observable의 인스턴스 메소드를 사용하여 시퀀스를 생성한다.
사용법은 이렇게 두 가지가 있다고 합니다!
참고자료: https://rhammer.tistory.com/311, https://ios-development.tistory.com/177