관리 메뉴

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

[iOS - swift] RxSwift - Switch Operator 연산자 amb(), Combine Operator 연산자 WithLatestFrom() 본문

RxSwift/RxSwift 기본

[iOS - swift] RxSwift - Switch Operator 연산자 amb(), Combine Operator 연산자 WithLatestFrom()

jake-kim 2022. 1. 24. 23:12

amb()

  • ambiguous (모호한)
  • switch 문과 역할 동일
  • 런타임 시점에 스트림을 변경하여 emit할 수 있게하는 연산자
    • let newObservable = left.amb(right) => left 스트림과 right 스트림 중 먼저 방출되는 스트림만 살아남고 나머지 하나는 무시

ex1)

let subjectEven = PublishSubject<Int>()
let subjectOdd = PublishSubject<Int>()

let newObservable = subjectEven.amb(subjectOdd)
let disposable = newObservable.subscribe(onNext: { value in
  print(value)
})

subjectOdd.onNext(1)
subjectOdd.onNext(3)

subjectEven.onNext(2) // <- 무시
subjectEven.onNext(4)

disposable.dispose()

// 1 3 5

ex2) 

subjectEven.onNext(2)
subjectOdd.onNext(1) // <- 무시
subjectOdd.onNext(3) // <- 무시
subjectEven.onNext(4)
  • amb() 연산자 사용 케이스)
    • 많은 서버 연결 시도 중 가장 먼저 응답을 준 서버와 통신하고 싶은 경우
    • back 버튼, next 버튼, close 버튼을 누른 처리를 위해 3개의 스트림이 있을 때, 3개의 스트림을 한꺼번에 묶어서 처리하고 싶은 경우 -> switch 문과 같이 사용
      Observable<Void>
      	.amb([
          	tapBackButtonObservable.map { Action.tapBack },
              tapNextButtonObservable.map { Action.tapNext },
              tapCloseButtonObservable.map { Action.tapClose },
          ])
          .take(1)
          .bind {
            switch $0 {
              case .tapBack:
              	...
              case .tabNext:
                  ...
              case .tabClose:
                  ...
            }
          }
          .disposed(by: self.disposeBag)​

WithLatestFrom()

  • A.withlatestFrom(B)
  • A가 방출될때마다, B의 최근 값과 결합하여 방출
  • 특정 이벤트가 발생했을 때, 최근에 다른 이벤트가 발생한 값을 사용하고 싶은 경우
    • 단, 최근에 다른 이벤트가 발생하지 않은 경우 방출하지 않고 대기

ex) 텍스트필드에 값을 입력한 후에 버튼을 탭한 경우, textField의 값을 받고 싶은 경우

- withLatestFrom(얻고싶은 값, resultSelector: { $0와 $1 중에 어떤 값을 선택할지 } )

self.loginButton.rx.tap
  .withLatestFrom(textField.rx.text, resultSelector: { $1 })
  .bind { print("입력 값 = \($0)") }
  .disposed(by: self.disposeBag)

ex) 버튼을 탭했을 때, 특정 인자를 API 요청에 사용하고 싶은 경우

self.loginButton.rx.tap
  .withLatestFrom(textField.rx.text, resultSelector: { $1 })
  .flatMap { inputText -> Observable<DataModel> in
    return MyAPI.request(.register(inputText))
  }
  .disposed(by: self.disposeBag)
Comments