Skip to content

Instantly share code, notes, and snippets.

Created July 9, 2016 07:54
Show Gist options
  • Save anonymous/7eb0e5cab274acbf1062b857fee6abc2 to your computer and use it in GitHub Desktop.
Save anonymous/7eb0e5cab274acbf1062b857fee6abc2 to your computer and use it in GitHub Desktop.
debounce in Swift 3
func debounce(delay: Int, queue: DispatchQueue, action: (()->()) ) -> ()->() {
var lastFireTime = DispatchTime.now()
let dispatchDelay = DispatchTimeInterval.seconds(delay)
return {
lastFireTime = DispatchTime.now()
let dispatchTime: DispatchTime = lastFireTime + dispatchDelay
queue.after(when: dispatchTime) {
let when: DispatchTime = lastFireTime + dispatchDelay
let now = DispatchTime.now()
if now.rawValue >= when.rawValue {
action()
}
}
}
}
func testDebounce() {
print(DispatchTime.now())
let queue = DispatchQueue.global(attributes: .qosDefault)
for i in [0...9] {
debounce(delay: 1, queue: queue, action: {
print(DispatchTime.now())
print("Fired")
})()
}
Thread.sleep(forTimeInterval: 2)
print(DispatchTime.now())
}
@aceontech
Copy link

Note that queue.after(when:) has actually been renamed to queue.asyncAfter(deadline:). And closure arguments are non-escaping by default now, so you need to add a @escaping:

public func debounce(delay: Int, queue: DispatchQueue = .main, action: @escaping (()->())) -> ()->() {
    var lastFireTime  = DispatchTime.now()
    let dispatchDelay = DispatchTimeInterval.seconds(delay)

    return {
        lastFireTime = DispatchTime.now()
        let dispatchTime: DispatchTime = lastFireTime + dispatchDelay

        queue.asyncAfter(deadline: dispatchTime) {
            let when: DispatchTime = lastFireTime + dispatchDelay
            let now = DispatchTime.now()
            if now.rawValue >= when.rawValue {
                action()
            }
        }
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment