Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Debounce + Throttle
import Dispatch
private var throttleWorkItems = [AnyHashable: DispatchWorkItem]()
private var lastDebounceCallTimes = [AnyHashable: DispatchTime]()
private let nilContext: AnyHashable = arc4random()
public extension DispatchQueue {
/**
- parameters:
- deadline: The timespan to delay a closure execution
- context: The context in which the throttle should be executed
- action: The closure to be executed
Delays a closure execution and ensures no other executions are made during deadline
*/
public func throttle(deadline: DispatchTime, context: AnyHashable? = nil, action: @escaping () -> Void) {
let worker = DispatchWorkItem {
defer { throttleWorkItems.removeValue(forKey: context ?? nilContext) }
action()
}
asyncAfter(deadline: deadline, execute: worker)
throttleWorkItems[context ?? nilContext]?.cancel()
throttleWorkItems[context ?? nilContext] = worker
}
/**
- parameters:
- interval: The interval in which new calls will be ignored
- context: The context in which the debounce should be executed
- action: The closure to be executed
Executes a closure and ensures no other executions will be made during the interval.
*/
public func debounce(interval: Double, context: AnyHashable? = nil, action: @escaping () -> Void) {
if let last = lastDebounceCallTimes[context ?? nilContext], last + interval > .now() {
return
}
lastDebounceCallTimes[context ?? nilContext] = .now()
async(execute: action)
// Cleanup & release context
throttle(deadline: .now() + interval) {
lastDebounceCallTimes.removeValue(forKey: context ?? nilContext)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.