본문 바로가기
RxSwift

[RxSwift] Operators - 결합(4)

by 고고 2021. 11. 20.

여러 개의 소스 Observable들을 하나의 Observable로 만드는 연산자들 - CombineLatest, merge, startwith, switch, zip, withLatestFrom, concat

안녕하세요 ◠‿◠ 고고입니다.

 

1. CombineLatest

  • CombineLatest — 두 개의 Observable 중 하나가 항목을 배출할 때 배출된 마지막 항목과 다른 한 Observable이 배출한 항목을 결합한 후 함수를 적용하여 실행 후 실행된 결과를 배출한다

구현부

public static func combineLatest<O1: ObservableType, O2: ObservableType>
        (_ source1: O1, _ source2: O2, resultSelector: @escaping (O1.Element, O2.Element) throws -> Element)
            -> Observable<Element> {
        return CombineLatest2(
            source1: source1.asObservable(), source2: source2.asObservable(),
            resultSelector: resultSelector
        )
    }

예시

let greetings = PublishSubject<String>()
let languages = PublishSubject<String>()

Observable.combineLatest(greetings, languages) { lhs, rhs -> String in
    return "\(lhs) \(rhs)"
	}
    .subscribe{ print($0) }

greetings.onNext("Hi")
languages.onNext("World!")
greetings.onNext("Hello")
languages.onNext("RxSwift")
greetings.onCompleted()
languages.onNext("SwiftUI")
languages.onCompleted()

// next(Hi World!)
// next(Hello World!)
// next(Hello RxSwift)
// next(Hello SwiftUI)
// completed

 

2. Merge

  • Merge — 복수 개의 Observable들이 배출하는 항목들을 머지시켜 하나의 Observable로 만든다

구현부

public func merge() -> Observable<Element.Element> {
        Merge(source: self.asObservable())
    }

예시

let subject1 = PublishSubject()
let subject2 = PublishSubject()

Observable.of(subject1, subject2)
   .merge()
   .subscribe {
       print($0)
   }

subject1.on(.Next(10))
subject1.on(.Next(11))
subject2.on(.Next(20))
subject2.on(.Next(21))
subject1.on(.Next(14))
subject1.on(.Completed)
subject2.on(.Next(22))
subject2.on(.Completed)

// next(10)
// next(11)
// next(12)
// next(20)
// next(21)
// next(14)
// next(22)
// completed

 

3. StartWith

  • StartWith — 소스 Observable이 항목을 배출하기 전에 다른 항목들을 앞에 추가한 후 배출한다

구현부

public func startWith(_ elements: Element ...)
        -> Observable<Element> {
            return StartWith(source: self.asObservable(), elements: elements)
    }

예시

let numbers = [1, 2, 3]

let source = Observable.from(numbers)
    .startWith(0)
    .startWith(-1)
    
source
    .subscribe { print($0) }

// next(-1)
// next(0)
// next(1)
// next(2)
// next(3)
// completed

 

 

4. Switch

  • Switch — Observable들을 배출하는 Observable을 싱글 Observable로 변환하다. 변환된 싱글 Observable은 변환 전 소스 Observable들이 배출한 항목들을 배출한다

구현부

public func switchLatest() -> Observable<Element.Element> {
        Switch(source: self.asObservable())
    }

예시

let greetings = PublishSubject<String>()
let languages = PublishSubject<String>()

let source = PublishSubject<Observable<String>>()

source
    .switchLatest()
    .subscribe{ print($0) }

greetings.onNext("Hi")
languages.onNext("World!")
source.onNext(greetings)

greetings.onNext("Hello")
languages.onNext("RxSwift")
source.onNext(languages)

greetings.onCompleted()
languages.onNext("SwiftUI")
languages.onCompleted()

// next(Hello)
// next(SwiftUI)
// completed

 

5. Zip

  • Zip — 명시한 함수를 통해 여러 Observable들이 배출한 항목들을 결합하고 함수의 실행 결과를 배출한다
  • 인덱스를 기준으로 짝을 일치시켜 전달한다

구현부

public static func zip<O1: ObservableType, O2: ObservableType>
        (_ source1: O1, _ source2: O2, resultSelector: @escaping (O1.Element, O2.Element) throws -> Element)
        -> Observable<Element> {
        return Zip2(
            source1: source1.asObservable(), source2: source2.asObservable(),
            resultSelector: resultSelector
        )
    }

예시

let greetings = PublishSubject<String>()
let languages = PublishSubject<String>()

Observable.zip(greetings, languages) { lhs, rhs -> String in
    return "\(lhs) \(rhs)"
	}
    .subscribe{ print($0) }

greetings.onNext("Hi")
languages.onNext("World!")
greetings.onNext("Hello")
languages.onNext("RxSwift")
greetings.onCompleted()
languages.onNext("SwiftUI")
languages.onCompleted()

// next(Hi World!)
// next(Hello RxSwift)
// completed

 

 

 

+)

6. Concat

  • 두개의 옵저버블을 연결할때 사용한다

구현부

public func concat<Source: ObservableConvertibleType>(_ second: Source) -> Observable<Element> where Source.Element == Element {
        Observable.concat([self.asObservable(), second.asObservable()])
    }

예시

let fruits = Observable.from(["🍏", "🍎"])
let animals = Observable.from(["🐶", "🐱"])

Observable.concat([fruits, animals])
    .subscribe{ print($0) }

// next(🍏)
// next(🍎)
// next(🐶)
// next(🐱)
// completed

 

7. withLatestFrom

  • 트리거 옵저버블이 Next 이벤트를 방출하면 데이터 옵저버블이 가장 최근에 방출한 Next 이벤트를 구독자에게 전달한다

구현부

public func withLatestFrom<Source: ObservableConvertibleType>(_ second: Source) -> Observable<Source.Element> {
        WithLatestFrom(first: self.asObservable(), second: second.asObservable(), resultSelector: { $1 })
    }

예시

let trigger = PublishSubject<Void>()
let data = PublishSubject<String>()

trigger.withLatestFrom(data)
    .subscribe { print($0) }
    .disposed(by: bag)

data.onNext("Hello")
trigger.onNext(())
trigger.onNext(())

data.onCompleted()
trigger.onNext(())

trigger.onCompleted()

----- RESULT -----
next(Hello)
next(Hello)
next(Hello)
completed

 

 

 

 

출처 : http://reactivex.io/documentation/ko/operators.html

 

ReactiveX - Operators

연산자 소개 ReactiveX를 지원하는 언어 별 구현체들은 다양한 연산자들을 제공하는데, 이 중에는 공통적으로 제공되는 연산자도 있지만 반대로 특정 구현체에서만 제공하는 연산자들도 존재한다

reactivex.io

'RxSwift' 카테고리의 다른 글

[RxSwift] Operators - 유틸리티(6)  (0) 2021.11.29
[RxSwift] Operators - 오류 처리(5)  (0) 2021.11.20
[RxSwift] Operators - 필터링(3)  (0) 2021.11.19
[RxSwift] Operators - 변환(2)  (0) 2021.11.19
[RxSwift] Opeators - 생성(1)  (0) 2021.11.19

댓글