[RxSwift] withLatestFrom

2019-12-24

역할

Observable중 첫번째 Observable에서 아이템이 방출될 때마다 그 아이템을 두번째 Observable가장 최근 아이템과 결합해 방출합니다.

withLatestFrom

예제

[코드]

let disposeBag = DisposeBag()
    
let numSubject  = PublishSubject<Int>()
let charSubject = PublishSubject<String>()
    
numSubject
    .withLatestFrom(charSubject) { "\($0)\($1)"}
    .subscribe(onNext: { print($0) })
    .disposed(by:disposeBag)
    
numSubject.onNext(1)     // 아이템 방출되지 않음 : charSubject에서 방출된 아이템이 아직 1개도 없으므로
    
charSubject.onNext("A")
    
numSubject.onNext(2)     // 2A
    
charSubject.onNext("B")
    
charSubject.onNext("C")
charSubject.onNext("D")
    
numSubject.onNext(3)     // 3D
numSubject.onNext(4)     // 4D
numSubject.onNext(5)     // 5D

[실행 결과]

2A
3D
4D
5D

numSubject에서 아이템이 방출될때만 withLatestFrom 연산이 수행됩니다. 첫번째 Observable에서 첫 아이템(A)이 방출된 시점에 두번째 Observable에서 방출된 아이템이 없으므로, 아무런 아이템이 방출되지 않고 그 이후 부터 아이템이 방출되는 것을 확인할 수 있습니다.

활용

첫번째 Observable: tap 이벤트

두번째 Observable: 이벤트에 대한 처리

Observable을 이렇게 구성 한 후 withLatestFrom 연산자를 이용해 결합하면, tap 이벤트가 발생 했을 때 필요한 데이터를 발생시키거나 관련된 처리를 하도록 사용할 수 있습니다.

withLatestFromUserful

[코드]

let disposeBag = DisposeBag()
    
let loginButton  = PublishSubject<Void>()
let usernameTextField = PublishSubject<String>()
    
loginButton
    .withLatestFrom(usernameTextField)
    .subscribe(onNext: { print($0) })
    .disposed(by:disposeBag)
    
usernameTextField.onNext("tome.kye")
    
loginButton.onNext(())      // "tome.kye" 아이템 방출
    
usernameTextField.onNext("tommy.kye")
    
loginButton.onNext(())      // "tomme.kye" 아이템 방출

[실행 결과]

tome.kye
tommy.kye

이 예제는 로그인 버튼 선택시 데이터를 전달합니다. .withLatestFrom(usernameTextField) 는 첫번째 Observable의 아이템과 합성하지 않고, 두번째 Observable 아이템만 그대로 전달합니다.

아래 이 코드는

loginButton
    .withLatestFrom(usernameTextField)
    .subscribe(onNext: { print($0) })
    .disposed(by:disposeBag)

다음과 같이 API를 찌르는데 필요한 인자를 전달하는 용도로도 사용 가능합니다.

loginButton
    .withLatestFrom(usernameTextField)
    .flatMap { username -> Observable<UserDataModel> in
    		return API.Request(username: username)
    }

[참 고]