replay
반복하는앵무새🦜에 대해 subscribe 하기 전에 "인사말"에서 이벤트를 방출하고 있었다. subscribe 를 늦게 하더라도 replay 에 선언한 buffer 1 만큼의 이전에 방출된 이벤트의 값을 가져올 수 있다.
물론, subscribe 이후 발생하는 이벤트에 대해서는 값을 가져온다.
print("----------replay----------")
let 인사말 = PublishSubject<String>()
let 반복하는앵무새🦜 = 인사말.replay(1)
반복하는앵무새🦜.connect()
인사말.onNext("1. hello")
인사말.onNext("2. hi")
반복하는앵무새🦜
.subscribe(onNext: {
print($0)
})
.disposed(by: disposeBag)
인사말.onNext("3. 안녕하세요")
----------replay----------
2. hi
3. 안녕하세요
replayAll
replayAll 은 이전에 방출된 이벤트의 값을 모두 가져온다.
print("----------replayAll----------")
let 닥터스트레인지 = PublishSubject<String>()
let 닥터스트레인지의타임스톤 = 닥터스트레인지.replayAll()
닥터스트레인지의타임스톤.connect()
닥터스트레인지.onNext("도르마무")
닥터스트레인지.onNext("거래를 하러왔다")
닥터스트레인지의타임스톤
.subscribe(onNext: {
print($0)
})
.disposed(by: disposeBag)
----------replayAll----------
도르마무
거래를 하러왔다
buffer
buffer 는 최대 count 개의 값을 갖는 Array 형태로 방출한다.
① timeSpan: .second(-) : 2초마다
② count: - 최대
print("----------buffer----------")
let source = PublishSubject<String>()
var count = 0
let timer = DispatchSource.makeTimerSource()
// 현재 시점부터 2초를 deadline 으로, 매번 1초 마다
timer.schedule(deadline: .now() + 2, repeating: .seconds(1))
// 이벤트가 반복될 때 마다 동작
timer.setEventHandler {
count += 1
source.onNext("\(count)")
}
timer.resume()
source
.buffer(
timeSpan: .seconds(2),
// 최대 2개의 값을 갖는 Array 형태로 방출
count: 2,
scheduler: MainScheduler.instance
)
.subscribe(onNext: {
print($0)
})
.disposed(by: disposeBag)
----------buffer----------
// 2초 내에 이 당시에는 1 밖에 못 받았기 때문에 1이라도 방출
["1"]
["2", "3"]
...
window
buffer 와 비슷하지만, Array 가 아닌 Observable 들을 방출한다.
print("----------window----------")
let 만들어낼최대Observable수 = 1
let 만들시간 = RxTimeInterval.seconds(2)
let window = PublishSubject<String>()
var windowCount = 0
let windowTimerSource = DispatchSource.makeTimerSource()
windowTimerSource.schedule(deadline: .now() + 2, repeating: .seconds(1))
windowTimerSource.setEventHandler {
windowCount += 1
window.onNext("\(windowCount)")
}
windowTimerSource.resume()
window
.window(
timeSpan: 만들시간,
// 하나의 observable 만 계속해서 element 를 방출
count: 만들어낼최대Observable수,
scheduler: MainScheduler.instance
)
.flatMap { windowObservable -> Observable<(index: Int, element: String)> in
return windowObservable.enumerated()
}
.subscribe(onNext: {
print("\($0.index)번째 Observable의 요소 \($0.element)")
})
.disposed(by: disposeBag)
----------window----------
0번째 Observable의 요소 1
0번째 Observable의 요소 2
0번째 Observable의 요소 3
...
delaySubscription
정상적으로 이벤트를 방출하지만, subscribe 를 지연시키는 연산자이다.
print("----------delaySubscription----------")
let delaySource = PublishSubject<String>()
var delayCount = 0
let delayTimerSource = DispatchSource.makeTimerSource()
delayTimerSource.schedule(deadline: .now() + 2, repeating: .seconds(1))
delayTimerSource.setEventHandler {
delayCount += 1
delaySource.onNext("\(delayCount)")
}
delayTimerSource.resume()
delaySource
// 5초를 지연시킨다.
.delaySubscription(.seconds(5), scheduler: MainScheduler.instance)
.subscribe(onNext: {
print($0)
})
.disposed(by: disposeBag)
----------delaySubscription----------
4
5
...
delay
전체 Sequence 자체를 뒤로 미루는 연산자이다.
print("----------delay----------")
let delaySubject = PublishSubject<Int>()
var delaySubjectCount = 0
let delaySubjectTimerSource = DispatchSource.makeTimerSource()
delaySubjectTimerSource.schedule(deadline: .now(), repeating: .seconds(1))
delaySubjectTimerSource.setEventHandler {
delaySubjectCount += 1
delaySubject.onNext(delaySubjectCount)
}
delaySubjectTimerSource.resume()
delaySubject
.delay(.seconds(3), scheduler: MainScheduler.instance)
.subscribe(onNext: {
print($0)
})
.disposed(by: disposeBag)
----------delay----------
2
3
4
...
interval
임의로 만들었던 Timer 를 Rx 로 만들어주는 연산자이다.
아래 코드에서는 3초 간격으로 Int 를 방출한다. (자동으로 타입 추론을 통해 Int 방출)
print("----------interval----------")
Observable<Int>
.interval(.seconds(3), scheduler: MainScheduler.instance)
.subscribe(onNext: {
print($0)
})
.disposed(by: disposeBag)
----------interval----------
// 3초 간격으로 Int 를 방출한다.
0
1
2
...
timer
interval 보다 조금 더 강력한 형태이다.
① subscribe 하고 첫 번째 값을 방출하는 사이에 마감일을 설정할 수 있다.
print("----------timer----------")
Observable<Int>
.timer(
.seconds(5), //구독 시작 딜레이
period: .seconds(2), //간격
scheduler: MainScheduler.instance
)
.subscribe(onNext: {
print($0)
})
.disposed(by: disposeBag)
----------timer----------
// 5초 후 2초 간격으로 이벤트 방출
0
1
2
timeout
아무런 이벤트가 발생하지 않은 채 정해준 시간을 초과하게 되면 timeout 에러가 발생하도록 한다.
print("----------timeout----------")
let 누르지않으면에러 = UIButton(type: .system)
누르지않으면에러.setTitle("눌러주세요!", for: .normal)
누르지않으면에러.sizeToFit()
PlaygroundPage.current.liveView = 누르지않으면에러
누르지않으면에러.rx.tap
.do(onNext: {
print("tap")
})
.timeout(.seconds(5), scheduler: MainScheduler.instance)
.subscribe {
print($0)
}
.disposed(by: disposeBag)
' iOS > RxSwift' 카테고리의 다른 글
RxSwift - extension Reactive는 무엇일까? (0) | 2023.01.19 |
---|---|
RxSwift - Error 관리 (0) | 2022.11.07 |
RxSwift - Sequence 내부의 요소들간의 결합 연산자(reduce, scan) (0) | 2022.11.07 |
RxSwift - 하나의 Observable 가 Trigger 역할 후 Observable 들을 조합하는 방법(withLatestFrom, sample, amb, switchLatest) (0) | 2022.11.06 |
RxSwift - 여러 개의 Observable 을 합치는 방법(startWith, concat, merge, zip) (0) | 2022.11.06 |