public func example(of description: String, action: () -> Void) {
print("\n--- Example of:", description, "---")
action()
}
var subscriptions = Set<AnyCancellable>()
Chapter 6: Time Manipulation Operators
반응현 프로그래밍의 핵심은 시간의 흐름에 따른 비동기 이벤트 흐름을 모델링 할 수 있다는 것 입니다.
이러한 측면에서 Combine 프레임워크는 시간을 다룰 수 있는 다양한 Operator를 제공합니다.
이번 챕터에서는 시간을 조작하는 연산자들에 대해 알아보도록 하겠습니다.
Shifting Time
가장 기본적인 시간 조작 operator는 publisher의 Event emit을 지연시켜서 실제 발생하는 것 보다 늦게 받아볼 수 있도록 하는 operator 입니다.
delay(for:tolerance:scheduler:options)
는 값 시퀀스 전체의 시간을 이동시킵니다.
즉 upstream publisher 에서 값이 emit 될 때 마다 delay
를 통해 Scheduler에 명시해놓은 시간만큼 지연 시킵니다.
example(of: "delay", action: {
let valuePerSecond = 1.0
let sourcePublisher = PassthroughSubject<Date, Never>()
let delayedPublisher = sourcePublisher
.delay(for: .seconds(1.5), scheduler: DispatchQueue.main)
let subscription = Timer
.publish(every: 1.0 / valuePerSecond, on: .main, in: .common)
.autoconnect() // value를 emit 하기 이전에 connect를 위하여 autoconnect 사용.
.subscribe(sourcePublisher)
})
// value를 1초 마다 emit하고 1.5초 delay를 진행합니다.
Collecting Values
- 특정 기간 동안 방출된 values를 모아줍니다.
- collect된 value들을 모아서 array 타입으로 반환합니다.
example(of: "collect", action: {
let valuesPerSecond = 1.0
let collectTimeStride = 4
let sourcePublisher = PassthroughSubject<Date, Never>()
let collectedPublisher = sourcePublisher
.collect(.byTime(DispatchQueue.main, .seconds(collectTimeStride)))
.flatMap { dates in dates.publisher }
let subscription = Timer
.publish(every: 1.0 / valuesPerSecond, on: .main, in: .common)
.autoconnect()
.subscribe(sourcePublisher)
})
Holding off on events
- debounce: 입력 주기가 끝났을때 event를 방출합니다.
- throttle: 입력 주기 내 입력값 중 첫번쨰 || 마지막 event를 방출합니다.
example(of: "debounce", action: {
let subject = PassthroughSubject<String, Never>()
let debounced = subject
.debounce(for: .seconds(1.0), scheduler: DispatchQueue.main)
.share() // 여러 subscriber에게 해당 publisher를 공유하기 위함.
})
debounce
operator는 입력 주기가 끝나면 마지막 값을 출력합니다.
이후 추가로 value가 들어올 경우 주기가 다시 갱신됩니다.
example(of: "throttle", action: {
let throttleDelay = 1.0
let subject = PassthroughSubject<String, Never>()
let throttled = subject
.throttle(for: .seconds(throttleDelay), scheduler: DispatchQueue.main, latest: false)
.share()
})
throttle
은 처음에 구독한 시점에 value를 바로 방출합니다.
latest 값을 false 로 줄 경우 특정 주기 안의 첫번째 value를 출력합니다.
버튼 이벤트를 여러번 하는 경우 이를 통해 대응할수 있습니다.
'iOS' 카테고리의 다른 글
[iOS] Using AVAudioEngine to Record Audio on iOS (0) | 2021.12.11 |
---|---|
[iOS] AVAudioEngine (0) | 2021.12.10 |
[iOS] Combine_Async_Programming - Combining Operators (0) | 2021.11.25 |
[iOS] Combine_Async_Programming - Filtering Operations (0) | 2021.11.22 |
[iOS] Combine_Async_Programming - Transforming Operators (0) | 2021.11.21 |