제네릭 구조체 | 주어진 시간 내에 상위 Publisher가 발행한 가장 최신 또는 첫 번째 요소를 발행하는 Publisher
이니셜라이저는 네 개의 인자를 받는다.
upstream
: 상위에 흐르는 Publisher
interval
: 가장 최신의 요소를 찾고 배출할 시간 간격
scheduler
: 요소를 발행하는 스케줄러
latest
: 가장 최신의 요소를 발행하는지를 가리키는 불리언 값
요소가 배출되고 주어진 시간이 지나고서야 그 시간 내에 배출된 첫 번째 또는 가장 최신의 요소를 발행한다.
debounce
는 주어진 시간 동안 값을 전달하지 않아야 마지막에 전달된 값을 발행하지만, throttle
은 주어진 시간이 지날 때 그 시간 내에 배출된 첫 번째 또는 가장 최신의 요소를 발행한다.
throttle
오퍼레이터와 관련이 있다.
let subject = PassthroughSubject<Int, Never>()
// Publishers.Throttle Publisher
Publishers.Throttle(upstream: subject, interval: .seconds(1), scheduler: DispatchQueue.main, latest: true)
.sink(receiveCompletion: { completion in
switch completion {
case .failure:
print("Combine Throttle Error")
case .finished:
print("Combine Throttle Finish")
}
}, receiveValue: { value in
print("Combine Throttle : \(value)")
})
.store(in: &cancellables)
// Combine Throttle : 9
// throttle Operator (latest: true)
subject
.throttle(for: .seconds(1), scheduler: DispatchQueue.main, latest: true)
.sink(receiveCompletion: { completion in
switch completion {
case .failure:
print("Combine Throttle Error")
case .finished:
print("Combine Throttle Finish")
}
}, receiveValue: { value in
print("Combine Throttle : \(value)")
})
.store(in: &cancellables)
// Combine Throttle : 9
// throttle Operator (latest: false)
subject
.throttle(for: .seconds(1), scheduler: DispatchQueue.main, latest: false)
.sink(receiveCompletion: { completion in
switch completion {
case .failure:
print("Combine Throttle Error")
case .finished:
print("Combine Throttle Finish")
}
}, receiveValue: { value in
print("Combine Throttle : \(value)")
})
.store(in: &cancellables)
// Combine Throttle : 0
for i in 0 ..< 10 {
subject.send(i)
}
1과 2의 코드는 값이 발행되면 1초의 카운트를 제어 카운트가 끝나면 해당 시간 내에 발행된 최신의 요소를 발행한다.
3의 코드는 값이 발행되면 1초의 카운트를 제어 카운트가 끝나면 해당 시간 내에 발행된 첫 번째 요소를 발행한다.
코드를 실행하면 반복문을 통해 0부터 9까지 subject
에 값을 전달하는데, 이 동작이 1초 안에 모두 이루어지므로 카운트가 끝날 때 스트림의 첫 번째 값은 0, 최신 값은 9일 것이다.
현재 런타임 에러가 발생하여 실제 동작을 확인할 수 없다. 포럼
RxSwift
throttle
오퍼레이터를 사용하여 구현할 수 있다.
카운트의 시작을 불러 일으키는 첫 번째 값과 카운트가 끝날 때의 최신 값을 모두 배출하는 것으로 구현되어 있다.
let subject = PublishSubject<Int>()
subject
.throttle(.seconds(1), scheduler: MainScheduler.instance)
.subscribe(onNext: { value in
print("RxSwift Throttle : \(value)")
}, onError: { _ in
print("RxSwift Throttle Error")
}, onCompleted: {
print("RxSwift Throttle Finish")
})
.disposed(by: disposeBag)
for i in 0 ..< 10 {
subject.onNext(i)
}
// RxSwift Throttle : 0
// RxSwift Throttle : 9
ReactiveSwift
throttle
오퍼레이터를 사용하여 구현할 수 있다.
let property = MutableProperty<Int>(0)
property.signal
.throttle(1, on: QueueScheduler.main)
.observe { event in
switch event {
case let .value(value):
print("ReactiveSwift Throttle : \(value)")
case .failed:
print("ReactiveSwift Throttle Error")
case .completed:
print("ReactiveSwift Throttle Finish")
default:
break
}
}
for i in 0 ..< 10 {
property.value = i
}
// ReactiveSwift Throttle : 9
참고
Publishers.Debounce