Creating에 속하는 Interval operator에 대해서 알아볼 것이다.
Interval
1. 정의
주어진 시간 간격을 두고 주기마다, emit되는 옵저버블을 생성한다. Interval 연산자의 경우 completed 되지 않고, 무한한 시퀀스를 생성한다. 즉, 직접 dispose 시키지 않는다면 구독 이후에 계속 반복되는 것이다!
2. 구현
Observables의 Timer에서 구현 내용을 살펴볼 수 있다.
public static func interval(_ period: RxTimeInterval, scheduler: SchedulerType) -> Observable<Element> {
return Timer(
dueTime: period,
period: period,
scheduler: scheduler
)
}
파라미터를 살펴보자.
- period : 주기를 의미한다. 1초로 설정하면 1초마다 옵저버블을 반한하게 되는 것이다
- scheduler : 작업을 수행할 스케줄러를 고른다.
3. 사용예시
// interval
let observable = Observable<Int>
.interval(.seconds(1), scheduler: MainScheduler.instance)
.subscribe { print($0) }
// 직접 해제시켜야함
DispatchQueue.main.asyncAfter(deadline: .now() + 6) {
observable.dispose()
}
// next(1)
// next(2)
// next(3)
// next(4)
// next(5)
interval과 비슷한 operator로 timer가 있는데 이 또한 같이 봐보자.
Timer
1. 정의
주어진 시간만큼 지난 이후 개별적으로 반환되는 옵저버블을 생성한다.
구독 이후에 딜레이를 가지고 옵저버블이 반환되는 것을 볼 수 있다. 또한 Interval과는 달리 유한한 시퀀스이다.
2. 구현
public static func timer(_ dueTime: RxTimeInterval, period: RxTimeInterval? = nil, scheduler: SchedulerType) -> Observable<Element> {
return Timer(
dueTime: dueTime,
period: period,
scheduler: scheduler
)
}
파라미터를 봐보자. interval과 유사해보이나 조금 다르다.
- dueTime : 첫 번째 값이 생성되기 까지의 상대적인 시간
- period : 다음 값이 생성되기 까지의 주기
- scheduler : 타이머가 작동될 스케줄러
즉, dueTime이 5초라면, 구독하고 나서 5초 뒤에 첫 번째 값을 받아볼 수 있는 것이다. 그리고 period를 보면 기본적으로 nil로 선언되어있음을 볼 수 있다. 따로 설정하지 않으면 다음 값을 뱉지 않는다고 봐도 된다. 스케줄러는 위에서 봤던대로 동일하다.
3. 사용 예시
// timer
Observable<Int>
.timer(.seconds(1), scheduler: MainScheduler.instance)
.subscribe { print($0) }
.disposed(by: disposeBag)
// next(0)
// completed
// timer with period
Observable<Int>
.timer(.seconds(1), period: .seconds(1), scheduler: MainScheduler.instance)
.subscribe { print($0) }
.disposed(by: disposeBag)
// next(0)
// next(1)
// next(2)
// next(3)
// next(4)
// :
interval에서의 seconds와 달리 여기서는 dueTime으로 전달된다. 즉 얼마나 지연시키고 첫 값을 받을지 정해주는 것이다. 위에서는 1초 기다렸다가 첫 번째 값을 받게 되는 것이다. 그리고 timer는 interval과 달리 complete 된다는 점!
period가 timer에 전달된다면, interval과 마찬가지로 직접 종료시켜줘야 한다. 위 코드는 1초 기다렸다가 매 1초간 값을 내뱉는 경우가 되는 것이다. disposeBag에 담았으니 일괄 종료 처리해줘도 되고, 개별적으로 dispose() 해줘도 된다.
Ref :
http://reactivex.io/documentation/operators/interval.html
http://reactivex.io/documentation/operators/timer.html
https://github.com/ReactiveX/RxSwift/blob/main/RxSwift/Observables/Timer.swift