Skip to content

Instantly share code, notes, and snippets.

@VladimirBrejcha
Last active September 21, 2023 06:14
Show Gist options
  • Save VladimirBrejcha/d68a9ef0016543ecd4a6fae7788a9eac to your computer and use it in GitHub Desktop.
Save VladimirBrejcha/d68a9ef0016543ecd4a6fae7788a9eac to your computer and use it in GitHub Desktop.
import Foundation
class Debounce {
private let queue: DispatchQueue
private let delay: Double
private var workItem: DispatchWorkItem?
private var cancelBlock: (() -> Void)?
init(queue: DispatchQueue, delay: Double) {
self.queue = queue
self.delay = delay
}
func callAsFunction(action: @escaping () -> Void, onCancel: (() -> Void)?) {
queue.async { [weak self] in
guard let self = self else {
onCancel?()
return
}
if let workItem = self.workItem {
workItem.cancel()
self.cancelBlock?()
}
let workItem = DispatchWorkItem {
self.cancelBlock = nil
action()
}
self.workItem = workItem
self.cancelBlock = onCancel
self.queue.asyncAfter(deadline: .now() + self.delay, execute: workItem)
}
}
}
// MARK: - Tests -
let queue = DispatchQueue(label: "DebounceQueue")
let debounce: Debounce = Debounce(queue: queue, delay: 0.2)
debounce {
print("action1 done")
} onCancel: {
print("action1 cancelled")
}
DispatchQueue.global().async {
debounce {
print("action2 done")
} onCancel: {
print("action2 cancelled")
}
}
DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + 0.2) {
debounce {
print("action3 done")
} onCancel: {
print("action3 cancelled")
}
}
DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + 0.3) {
debounce {
print("action33 done")
} onCancel: {
print("action33 cancelled")
}
}
DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + 0.4) {
debounce {
print("action34 done")
} onCancel: {
print("action34 cancelled")
}
}
DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + 0.5) {
debounce {
print("action35 done")
} onCancel: {
print("action35 cancelled")
}
}
DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + 0.6) {
debounce {
print("action36 done")
} onCancel: {
print("action36 cancelled")
}
}
DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + 0.7) {
debounce {
print("action37 done")
} onCancel: {
print("action37 cancelled")
}
}
DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + 0.8) {
debounce {
print("action38 done")
} onCancel: {
print("action38 cancelled")
}
}
DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + 0.9) {
debounce {
print("action39 done")
} onCancel: {
print("action39 cancelled")
}
}
queue.async {
debounce {
print("action4 done")
} onCancel: {
print("action4 cancelled")
}
}
queue.asyncAfter(deadline: DispatchTime.now() + 0.5) {
debounce {
print("action5 done")
} onCancel: {
print("action5 cancelled")
}
}
queue.asyncAfter(deadline: DispatchTime.now() + 1.5) {
debounce {
print("action6 done")
} onCancel: {
print("action6 cancelled")
}
}
queue.asyncAfter(deadline: DispatchTime.now() + 1.6) {
debounce {
print("action7 done")
} onCancel: {
print("action7 cancelled")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment