Plain Debounce implementation

Updated
May 31, 2021 10:12 AM
Created
May 31, 2021 10:12 AM
Tags
Swift
Keywords

final class Debounce {
  private var timerReference: DispatchSourceTimer?

  let interval: DispatchTimeInterval
  let queue: DispatchQueue

  public init(
    interval: DispatchTimeInterval,
    queue: DispatchQueue = .main
  ) {
    self.interval = interval
    self.queue = queue
  }

  public func on(handler: @escaping () -> Void) {
    let deadline = DispatchTime.now() + interval

    timerReference?.cancel()

    let timer = DispatchSource.makeTimerSource(queue: queue)
    timer.schedule(deadline: deadline)

    timer.setEventHandler(handler: { [weak timer, weak self] in
      timer?.cancel()
      self?.timerReference = nil
      handler()
    })
    timer.resume()

    timerReference = timer
  }

  public func cancel() {
    timerReference = nil
  }
}