웰코발
웰코's iOS
웰코발
전체 방문자
오늘
어제
  • 분류 전체보기 (63)
    • Swift (26)
    • rxSwift (13)
    • SwiftUI (3)
    • iOS (12)
    • 기타 (1)
    • 개발관련 용어정리 (6)
    • 면접준비 (0)
    • 공공데이터 (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • rxswift
  • UI
  • SWIFT
  • collectionview
  • 디자인
  • content_available
  • swiftUI
  • Scroll
  • 주제구독
  • uitableview
  • ReactorKit
  • 측정소정보
  • Coordinator
  • 대기오염통계 현황
  • Observable
  • alamofire
  • WKWebView
  • cell
  • delay
  • ios

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
웰코발

웰코's iOS

[rxSwift] Combining Operator 의 종류
rxSwift

[rxSwift] Combining Operator 의 종류

2022. 10. 27. 20:17

Combining Operator 의 종류

startWith

  • Observable 시퀀스 앞에 새로운 초기값을 추가함.

var disposeBag = DisposeBag()

let classRoom = Observable.of("student1","student2","student3")

classRoom
    .starWith("teacher")
    .subscribe(onNext: {
        print($0)
    })
    .disposed(by: disposeBag)


// teacher
// student1
// student2
// student3

 

 

concat

  • 같은 데이터 타입의 요소를 갖는 두개의 Observable들을 묶을 때 사용함.

var disposeBag = DisposeBag()

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

Observable
    .concat([first, second])
    .subscribe(onNext: { value in 
        print(value) 
    })
    .disposed(by: disposeBag)
    
// 1
// 2
// 3
// 4
// 5
// 6


first
    .concat(second)
    .subscribe(onNext: { value in 
        print(value) 
    })
    .disposed(by: disposeBag)

// 1
// 2
// 3
// 4
// 5
// 6

 

 

concatMap

  • 각각의 시퀀스가 다음 스퀀스가 구독되기 전에 합쳐짐을 보증함.
  • 즉, flatMap 같은 경우 각각의 시퀀스는 파이프라인 병행식으로 진행하는 반면,
  • concatMap은 시퀀스 순서대로 직렬로 합쳐짐을 보증해줌.

ConcatMap
flatMap

let sequences = [ 
        "room1": Observable.of("student1", "student2", "student3"), 
        "room2": Observable.of("student4", "student5", "student6") 
    ] 

var disposeBag = DisposeBag()

let observable = Observable.of("room1", "room2")

observable
    .flatMap { room in 
        sequences[room] ?? .empty()
    }
    .subscribe({
        print($0.element ?? "")
    })
    .disposed(by: disposeBag)
    
// room1 구독
// student1
// student2
// room2 구독
// student4   <- 엇갈리면서 순서 보장이 안됨.
// student3
// student5
// student6


observable
    .concatMap { room in 
        sequences[room] ?? .empty()
    }
    .subscribe({
        print($0.element ?? "")
    })
    .disposed(by: disposeBag)

// room1 구독
// student1
// student2
// student3     <- room1 seq가 완전히 끝난 후 room2 seq 진행
// room2 구독
// student4
// student5
// student6

 

 

merge

  • sequence들을 합치는 방법 중 하나
  • merge하고 있는 여러 시퀀스들을 동시에 구독하면서 먼저 오는 이벤트들을 바로 방출함. (선착순)
  • 최대 몇 개까지의 시퀀스를 합칠 것인지 정할 수 있음.
  • 내부 시퀀스가 종료되면 merge 시퀀스도 종료됨.
  • 내부 시퀀스가 complete되는 시점은 모두 독립적.
  • 만약 내부 시퀀스에서 error가 방출하면 merge 시퀀스도 에러를 방출시키면 종료됨.

var disposeBag = DisposeBag()

let left = PublishSubject()  
let right = PublishSubject()

let source = Observable.of(left.asObservable(), right.asObservable())  

let observable = source.merge()  


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

left.onNext(1)  
right.onNext(4)
right.onNext(5)
left.onNext(2)  
right.onNext(6)
left.onNext(3)

// 1
// 4
// 5
// 2
// 6
// 3

 

 

combineLatest

  • 두 개의 시퀀스를 하나의 시퀀스로 합침.
  • 서브 시퀀스에서 이벤트가 방출할 때 마다 이벤트를 방출함.
  • 서브 이벤트에서 최초 이벤트가 방출해야지만 합쳐진 시퀀스에서 이벤트가 방출함.

var disposeBag = DisposeBag()

let left = PublishSubject()  
let right = PublishSubject()

let observable = Observable
                    .combineLatest(left, right, 
                                    resultSelector: { lastLeft, lastRight in
                                        "(lastLeft), (lastRight)"  
                                    })
                                    .disposed(by: disposeBag)

let disposable = observable
                    .subscribe(onNext: { value in  
                        print(value)  
                    })
                    .disposed(by: disposeBag)

left.onNext(1)
right.onNext(4)  
right.onNext(5)  
left.onNext(2)  
right.onNext(6)   
left.onNext(3)  

// 1, 4
// 1, 5
// 2, 5
// 2, 6
// 3, 6

 

zip

  • 결합을 원하는 각각의 시퀀스들의 요소들을 순차적으로 결합함.
  • 둘중 하나의 Observable이 완료되면 zip에대한 Observable은 종료함.
  • 두 개 이상의 Observable에서 방출된 순서가 같은 아이템을 묶어서 하나의 아이템으로 방출함.

let disposeBag = DisposeBag()
    
let numSubject = PublishSubject<Int>()
let charSubject = PublishSubject<String>()
    
let zippedObservable = Observable.zip(numSubject, charSubject)
    
zippedObservable
    .subscribe(onNext: { print($0) })
    .disposed(by: disposeBag)
    
numSubject.onNext(1)
charSubject.onNext("A")
numSubject.onNext(2)
charSubject.onNext("B")
charSubject.onNext("C")
charSubject.onNext("D")
numSubject.onNext(3)
numSubject.onNext(4)
numSubject.onNext(5)

// 1A
// 2B
// 3C
// 4D

// 5는 결합하지 못한상태로 방출되지못함.

 

combineLatest과 zip의 비교

 

 

withLatestFrom

  • withLatestFrom을 호출한 Observable은 onNext하면 withLatestFrom의 파라미터인 Observable의 최신값을 trigger함.
  • 특정 트리거가 방출 됐을 때 특정 상태의 최신 값을 얻고 싶을 때 사용

var disposeBag = DisposeBag()

let button = PublishSubject<Void>()
let textField = PublishSubject<String>()

button
    .withLatestFrom(textField)
    .subscribe(onNext: {
       print($0)
     })
    .disposed(by: disposeBag)

textField.onNext("par")
textField.onNext("pari")
textField.onNext("paris")

button.onNext(Void())
button.onNext(Void())


// paris
// paris

 

 

sample

  • withLatestFrom 처럼 trigger 역할을 하지만 단 한번만 trigger함
  • withLastFrom과 비슷하게 sample이 있는데 이것은 중복된 값이 들어올 경우 이벤트는 한번만 방출된다

var disposeBag = DisposeBag()

let button = PublishSubject<Void>()
let textField = PublishSubject<String>()

button
    .sample(textField)
    .subscribe(onNext: {
       print($0)
     })
    .disposed(by: disposeBag)

textField.onNext("par")
textField.onNext("pari")
textField.onNext("paris")

button.onNext(Void())
button.onNext(Void())


// paris

 

 

그 외 Combining Operator

  • reduce
  • scan
  • switchLatest
  • amb
  • .... 등등

 

'rxSwift' 카테고리의 다른 글

[rxSwift] TimeBased Operator 의 종류  (0) 2022.10.29
[rxSwift] Transforming Operator 의 종류  (0) 2022.10.23
[rxSwift] Filtering Operator 의 종류  (0) 2022.10.22
[rxSwift] Subject 를 wrapping한 Relay 사용법  (0) 2022.10.21
[rxSwift] Subject 에 대한 이해와 종류  (0) 2022.10.21
    'rxSwift' 카테고리의 다른 글
    • [rxSwift] TimeBased Operator 의 종류
    • [rxSwift] Transforming Operator 의 종류
    • [rxSwift] Filtering Operator 의 종류
    • [rxSwift] Subject 를 wrapping한 Relay 사용법
    웰코발
    웰코발
    나의 개발 일지

    티스토리툴바