# interval
설정한 시간 주기에 맞춰 1씩 증가하는 정수를 이벤트로 방출하는 연산자이다.
let i = Observable<Int>.interval(.seconds(1), scheduler: MainScheduler.instance)
let subscription1 = i.subscribe { print("1 >> \($0)")} // next(0), next(1) ...
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
subscription1.dispose() // 5초 뒤 dispose
}
인터벌 연산자는 타이머가 발동되는 시점이 옵저버블을 생성한 때가 아닌 구독자가 구독한 시점부터 이루어진다.
let i = Observable<Int>.interval(.seconds(1), scheduler: MainScheduler.instance)
var subscription2: Disposable? // 구독작 Disposable타입으로 선언
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
subscription2 = i.subscribe{ print("2 >> \($0)") } // 2초 뒤 구독
}
DispatchQueue.main.asyncAfter(deadline: .now() + 7){
subscription2?.dispose() // 2~7초까지 이벤트 방출
}
# timer
타이머 연산자는 이벤트 전달 시점과 이벤트 방출 주기를 직접 설정할 수 있는 연산자이다.
_ duetime
: dueTime에 전달된 시점 이후에 첫 이벤트가 전달된다.period: RxTimeInterval? = nil
: 이벤트 방출 주기를 설정한다.nil
인 경우 이벤트를 하나만 방출하고 끝낸다.scheduler
: 스케줄러를 지정한다.
var bag = DisposeBag()
let subscription = Observable<Int>.timer(.seconds(1), period: .seconds(1), scheduler: MainScheduler.instance)
.subscribe{ print($0) }
DispatchQueue.main.asyncAfter(deadline: .now() + 5){
subscription.disposed(by: bag)
bag = DisposeBag()
}
- 1초 뒤에 정수를 이벤트로 방출한다.
- 이후 1초마다 정수를 계속해서 방출한다.
- 5초 뒤
DisposeBag
을 초기화하여 내부 옵저버블을 종료한다.
# timeout
타임아웃 연산자는 지정된 시간 내에 소스 옵저버블에서 이벤트가 방출되지 않는 경우 에러를 방출한다.
let bag = DisposeBag()
// 소스 옵저버블
let subject = PublishSubject<Int>()
subject.timeout(.seconds(3), scheduler: MainScheduler.instance)
.subscribe{ print($0) }
.disposed(by: bag)
// .timer(.seconds(4), ...) -> Error
Observable<Int>.timer(.seconds(0), period: .seconds(1), scheduler: MainScheduler.instance)
.subscribe{ subject.onNext($0) }
.disposed(by: bag)
- 3초 타임아웃을 지정하고 구독해둔다.
- 새로운 옵저버블에서 타이머 연산자를 통해 1초마다 정수를 소스 옵저버블로 방출한다.
- 매 초마다 정수가 정상적으로 전달되므로 소스 옵저버블인 서브젝트는 에러를 반환하지 않는다.
- 타이머 연산자의
dueTime
파라미터값을 3초보다 더 큰값을 지정하면 서브젝트에서 에러를 방출한다.
또한 타임아웃에는 other
파라미터도 지정할 수 있다. 타임아웃 기한까지 이벤트 방출이 이루어지지 않을 경우 대체할 옵저버블을 전달한다.
// other에 정수 0만 전달하는 옵저버블 지정
subject.timeout(.seconds(3), other: Observable.just(0) , scheduler: MainScheduler.instance)
.subscribe{ print($0) }
.disposed(by: bag)
Observable<Int>.timer(.seconds(4), period: .seconds(1), scheduler: MainScheduler.instance)
.subscribe{ subject.onNext($0) }
.disposed(by: bag)
# delay, delaySubscription
딜레이 연산자는 이벤트 방출 후 구독자로 전달되는 시점을 딜레이시킨다. 구독시점 및 이벤트 방출 시점 자체를 딜레이시키는 것이 아니다.
Observable<Int>.interval(.seconds(1), scheduler: MainScheduler.instance)
.take(5)
.delay(.seconds(5), scheduler: MainScheduler.instance)
.subscribe{ print($0) }
.disposed(by: bag)
- 1초마다 정수를 방출하는 인터벌 연산자를 사용한다.
- take 연산자를 통해 5개의 이벤트를 취한다.
- 차례로 방출되는 5개의 이벤트들을 각각 5초 뒤에 구독자에게 전달한다. (이벤트 방출은 이루어진 상태이다.)
반면 delaySubscription
연산자는 구독 시점 자체를 지연시킨다.
Observable<Int>.interval(.seconds(1), scheduler: MainScheduler.instance)
.take(5)
.debug()
.delaySubscription(.seconds(5), scheduler: MainScheduler.instance)
.subscribe{ print($0) }
.disposed(by: bag)
디버그 연산자를 사용하면 코드 흐름을 쉽게 파악할 수 있다.
- 정수 이벤트 5개를 받는다.
- 구독시점을 5초 뒤로 딜레이시켰으므로, 5초동안 아무것도 출력되지 않는다.