Debounce Rapid Function Calls
Coalesce bursts of events into one delayed function call using time.AfterFunc and a mutex-protected timer per debouncer.
Code
package main
import (
"fmt"
"sync"
"time"
)
type Debouncer struct {
mu sync.Mutex
delay time.Duration
timer *time.Timer
}
func NewDebouncer(delay time.Duration) *Debouncer {
return &Debouncer{delay: delay}
}
func (d *Debouncer) Do(fn func()) {
d.mu.Lock()
defer d.mu.Unlock()
if d.timer != nil {
d.timer.Stop()
}
d.timer = time.AfterFunc(d.delay, fn)
}
func (d *Debouncer) Stop() {
d.mu.Lock()
defer d.mu.Unlock()
if d.timer != nil {
d.timer.Stop()
}
}
func main() {
var wg sync.WaitGroup
wg.Add(1)
debounce := NewDebouncer(50 * time.Millisecond)
start := time.Now()
for index := 0; index < 5; index++ {
debounce.Do(func() {
fmt.Println("fired after", time.Since(start).Round(time.Millisecond))
wg.Done()
})
time.Sleep(10 * time.Millisecond)
}
wg.Wait()
}
Report a problem with this exampleOpens a pre-filled issue on GitHub.