본문 바로가기
iOS/RxSwift

[RxSwift] concat

by Jiseong 2022. 7. 26.

최근에 ReactorKit을 적용해보면서 많이 사용하였던 concat에 대해서 알아보려한다. 

 

꽤나 간단하다.

 

concat여러 Observable을 연결하는 오퍼레이터이다.

 

모든 Observable이 정상적으로 완료되고, 마지막에 연결된 tail부의 Observable이 완료되면 complete된다.

 

그냥 쉽게 생각하면 직렬로 Observable을 연결한다 라고 생각하면 된다. 

 

예제는 다음과 같다.

let disposeBag = DisposeBag()

let eng = Observable.of("a", "b", "c")
let kor = Observable.of("ㄱ", "ㄴ", "ㄷ")

let 변수명정하기시로시로 = Observable
    .concat([eng, kor])

변수명정하기시로시로
    .subscribe(onNext: {
        print($0)
    })
    .disposed(by: disposeBag)
    
// 결과
// a
// b
// c
// ㄱ
// ㄴ
// ㄷ

앞서 처리해야할 것들을 처리한 뒤 다음 것들을 처리해야하는 상황에 많이 쓰인다.

 

위 marble을 보면 하나의 스트림에서 내려오는 이벤트를 순차적으로 실행한 뒤 다음 스트림의 이벤트를 순차적으로 실행하는 오퍼레이터임을 알 수 있다.

// Concatenates the second observable sequence to `self` upon successful termination of `self`.
public func concat<Source: ObservableConvertibleType>(_ second: Source) -> Observable<Element> where Source.Element == Element {
        Observable.concat([self.asObservable(), second.asObservable()])
}

// Concatenates all observable sequences in the given sequence, as long as the previous observable sequence terminated successfully.
public static func concat<Sequence: Swift.Sequence>(_ sequence: Sequence) -> Observable<Element>
        where Sequence.Element == Observable<Element> {
            return Concat(sources: sequence, count: nil)
}

// Concatenates all observable sequences in the given collection, as long as the previous observable sequence terminated successfully.
public static func concat<Collection: Swift.Collection>(_ collection: Collection) -> Observable<Element>
        where Collection.Element == Observable<Element> {
            return Concat(sources: collection, count: Int64(collection.count))
}

// Concatenates all observable sequences in the given collection, as long as the previous observable sequence terminated successfully.
public static func concat(_ sources: Observable<Element> ...) -> Observable<Element> {
        Concat(sources: sources, count: Int64(sources.count))
}

다양하게 Overloading이 되어있지만, 그저 타입의 차이이다. 

 

메서드의 제네릭을 보면 알 수 있듯 연결될 Observable의 타입이 모두 같아야하는 것을 알 수 있다.

func on(_ event: Event<Element>){
        switch event {
        case .next:
            self.forwardOn(event)
        case .error:
            self.forwardOn(event)
            self.dispose()
        case .completed:
            self.schedule(.moveNext)
     }
 }

또한 순차적으로 Observable 이벤트를 처리하는 도중 에러가 발생한다면 뒤로 붙은 Observable은 무시되며 dispose되어 종료된다.

이외에 주의할 점은 Hot Observable의 경우 구독을 하지않아도 이벤트를 방출하고 있으므로 직렬 연결된 Observable을 순차적으로 구독하여 실행하는 concat의 경우엔 Hot Observable의 순서가 오기전에 방출된 Hot Observable의 이벤트는 전부 무시되기 때문에 적절치 못하다.

 

https://reactivex.io/documentation/operators/concat.html

 

ReactiveX - Concat operator

RxKotlin implements this operator as concat. There are variants of this operator that take between two and nine Observables as parameters, and that concatenate them in the order they appear in the parameter list. There is also a variant that takes as a par

reactivex.io

https://github.com/ReactiveX/RxSwift/blob/1a1fa37b0d08e0f99ffa41f98f340e8bc60c35c4/RxSwift/Observables/Concat.swift

 

GitHub - ReactiveX/RxSwift: Reactive Programming in Swift

Reactive Programming in Swift. Contribute to ReactiveX/RxSwift development by creating an account on GitHub.

github.com

블로그 간만에 쓰네...^^ 이럼 안되는데^^;;;

'iOS > RxSwift' 카테고리의 다른 글

[RxSwift] flatMapLatest (feat. flatMap)  (1) 2022.08.09
[RxSwift] map vs flatMap  (0) 2022.08.09
[RxSwift] RxDataSources 사용해보기  (0) 2022.08.02
[RxSwift] Hot vs Cold Observable  (0) 2022.06.08
[RxSwift] Observable, Dispose  (0) 2022.03.20

댓글