관리 메뉴

김종권의 iOS 앱 개발 알아가기

[RxSwift] 6. merge, combineLatest, withLatestFrom, zip, concat, 본문

RxSwift/RxSwift 응용

[RxSwift] 6. merge, combineLatest, withLatestFrom, zip, concat,

jake-kim 2020. 9. 27. 01:17

merge

단순히 모든 event를 결합 (단 순서는 번갈아 가며)

let disposeBag = DisposeBag()

let first = Observable.of(1, 2, 3)
let second = Observable.of(4, 5, 6)

Observable.merge(first, second)
    .subscribe(onNext: { print($0) })
    .disposed(by: dispseBag)

/* Prints:
1
4
2
5
3
6
*/

combineLatest

여러 소스 중에서 단 한 가지라도 이벤트를 방출하면, 각각 소스의 맨 마지막 값을 뽑아서 새로운 값을 방출

한 번 값을 방출한 이후에는 클로저가 각각의 Observable이 방출했었던 최신 값을 받음

- ex) 이메일과 비밀번호가 변할 때마다 버튼의 enabled 를 계산할 때

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
*/

withLatestFrom

  • combineLatest와 차이
    • combineLatest은 어떤 값이든 상관 안하고 한쪽이 이벤트가 발생하면 모두 방출
    • withLatestFrom()은 2가지 조건이 만족해야 방출
      • 괄호 안에 들어가는 Observable이 한번 이상 방출된 상태에서 시작 (그 전에는 모든 이벤트 무시)
      • 그 이후에 withLatestFrom 메소드를 호출한 Observable의 이벤트가 발생한 경우 방출
// withLatestFrom
oddNumber.withLatestFrom(evenNumber) { "\($0) \($1)"}
    .subscribe(onNext: { print("\($0)") })
    .disposed(by: bag)

oddNumber.onNext(1) // emit x
evenNumber.onNext(2) // emit x

evenNumber.onNext(4) // emit x
oddNumber.onNext(3) // 3 4
oddNumber.onNext(5) // 5 4
oddNumber.onNext(7) // 7 4

// combineLatest
Observable.combineLatest(oddNumber, evenNumber)
    .subscribe(onNext: { print("\($0) \($1)") })
    .disposed(by: bag)

oddNumber.onNext(1) // emit x
evenNumber.onNext(2) // 1 2

evenNumber.onNext(4) // 1 4
oddNumber.onNext(3) // 3 4
oddNumber.onNext(5) // 5 4
oddNumber.onNext(7) // 7 4

zip

발생 순서가 같은 이벤트만 발생 (순서가 다르면 발생하지 않음)

let disposeBag = DisposeBag()

let first = Observable.of(1, 2, 3, 4)
let second = Observable.of("A", "B", "C")

Observable.zip(first, second)
    .subscribe(onNext: { print("\($0)" + $1) })
    .disposed(by: dispseBag)
    
/* Prints:
1A
2B
3C
*/

concat

평등하게, 먼저 온 Observable을 방출 한 후, 나중에 온 Observable을 그 뒤에 방출

let first = Observable.of(1, 2, 3)
let second = Observable.of(4, 5, 6)

let observable = Observable.concat([first, second])

observable.subscribe(onNext: {
   print($0)
})

/* Prints:
 1
 2
 3
 4
 5
 6
*/

 

Comments