fimuxd/RxSwift를 참고해 정리하는 글입니다 🙂
Observable에서 항목을 방출하기 전에 지정된 항목 시퀀스를 방출
let numbers = Observable.of(2, 3, 4)
numbers
.startWith(1)
.subscribe(onNext: {
print($0)
})
// Prints: 1 -> 2 -> 3 -> 4
두 개 이상의 Observable을 끼워놓지 않고 방출합니다.
let first = Observable.of(1, 2, 3)
let second = Observable.of(4, 5, 6)
let observable = Observable.concat([first, second])
observable.subscribe(onNext: {
print($0)
})
/* Prints:
1
2
3
4
5
6
*/
concat
된 observable도 에러를 방출하며 완전 종료let germanCities = Observable.of("Berlin", "Münich", "Frankfurt")
let spanishCities = Observable.of("Madrid", "Barcelona", "Valencia")
let observable = germanCities.concat(spanishCities)
observable.subscribe(onNext: { print($0) })
Observable.concat
과 똑같이 작동let sequences = ["Germany": Observable.of("Berlin", "Münich", "Frankfurt"),
"Spain": Observable.of("Madrid", "Barcelona", "Valencia")]
Observable.of("Germany", "Spain")
.concatMap({ country in
sequences[country] ?? .empty()
})
.subscribe(onNext: {
print($0)
})
// Berlin
// Münich
// Frankfurt
// Madrid
// Barcelona
// Valencia
단일 Observable처럼 작동하도록 여러 Observable의 출력을 결합
merge()
는 즉시 에러를 방출하고 종료각 Observable에서 방출된 최신 항목을 결합하고 이 함수의 결과에 따라 항목을 방출
Observable 중 하나가 항목을 방출하면 CombineLatest는 제공한 함수를 사용하여 다른 소스 Observable 각각에서 가장 최근에 방출된 항목을 결합하고 해당 함수에서 반환 값을 방출
let left = PublishSubject<String>()
let right = PublishSubject<String>()
Observable
.combineLatest(left, right, resultSelector: { lastLeft, lastRight in
"\(lastLeft) \(lastRight)"
})
.subscribe(onNext: {
print($0)
}).disposed(by: disposeBag)
left.onNext("Hello,")
right.onNext("world")
right.onNext("RxSwift")
left.onNext("Have a good day,")
// Hello, world
// Hello, RxSwift
// Have a good day, RxSwift
Observable
.combineLatest([left, right]) { strings in
strings.joined(separator: " ")
}
enum Weather {
case cloudy
case sunny
}
let left: Observable<Weather> = Observable.of(.sunny, .cloudy, .cloudy, .sunny)
let right = Observable.of("Lisbon", "Copenhagen", "London", "Madrid", "Vienna")
Observable.zip(left, right, resultSelector: { (weather, city) in
return "It's \(weather) in \(city)"
})
.subscribe(onNext: {
print($0)
})
.disposed(by: disposeBag)
// It's sunny in Lisbon
// It's cloudy in Copenhagen
// It's cloudy in London
// It's sunny in Madrid
zip
역시 완료된다.combineLatest
처럼 2 ~ 8개의 observable에 대한 조합을 제공할 수 있다let button = PublishSubject<Void>()
let textField = PublishSubject<String>()
button.withLatestFrom(textField)
.subscribe(onNext: {
print($0)
})
.disposed(by: disposeBag)
textField.onNext("Par")
button.onNext(())
textField.onNext("Pari")
textField.onNext("Paris")
button.onNext(())
// Par
// Paris
withLatestFrom(_:)
과 거의 똑같이 작동하지만, 한 번만 방출textField.sample(button)
.subscribe(onNext: {
print($0)
})
.disposed(by: disposeBag)
textField.onNext("Par")
textField.onNext("Pari")
textField.onNext("Paris")
button.onNext(())
button.onNext(())
// Paris
withLatestFrom(_:)
은 데이터 observable을 파라미터로 받고, sample(_:)
은 trigger observable을 파라미터로 받는다.둘 이상의 Observable이 주어지면 첫 번째로 방출 Observable에서만 모든 항목을 방출
let left = PublishSubject<String>()
let right = PublishSubject<String>()
left.amb(right)
.subscribe(onNext: { value in
print(value)
})
.disposed(by: disposeBag)
left.onNext("Lisbon")
right.onNext("Copenhagen")
left.onNext("London")
left.onNext("Madrid")
right.onNext("Vienna")
// Lisbon
// London
// Madrid
let one = PublishSubject<String>()
let two = PublishSubject<String>()
let source = PublishSubject<Observable<String>>()
source.switchLatest()
.subscribe(onNext: {
print($0)
})
.disposed(by: disposeBag)
source.onNext(one)
one.onNext("Some text from sequence one")
two.onNext("Some text from sequence two")
source.onNext(two)
two.onNext("More text from sequence two")
one.onNext("and also from sequence one")
source.onNext(one)
one.onNext("Nope. It's me, one!")
// Some text from sequence one
// More text from sequence two
// Nope. It's me, one!
flatMapLatest(_:)
과 유사source.reduce(0, accumulator: +)
.subscribe(onNext: {
print($0)
})
.disposed(by: disposeBag)
// 25
0
)부터 시작해서 source observable이 값을 방출할 때마다 그 값을 가공하고 완료되면 방출source.reduce(0, accumulator: { summary, newValue in
return summary + newValue
})
.subscribe(onNext: {
print($0)
})
.disposed(by: disposeBag)
// 위 코드와 동일
Observable이 내보낸 각 항목에 함수를 순차적으로 적용하고 각 연속 값을 방출
let source = Observable.of(1, 3, 5, 7, 9)
source.scan(0, accumulator: +)
.subscribe(onNext: {
print($0)
})
.disposed(by: disposeBag)
// 1
// 4
// 9
// 16
// 25
reduce
와 비슷하지만 적용한 값을 계속 방출