Skip to content

Instantly share code, notes, and snippets.

@xeoncross
Last active October 23, 2018 20:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xeoncross/eebe80dbb0c1fdc6c44987f9821fc8bf to your computer and use it in GitHub Desktop.
Save xeoncross/eebe80dbb0c1fdc6c44987f9821fc8bf to your computer and use it in GitHub Desktop.
A better debounce function for Golang that prevents duplicate calls and ensures consistent timing. This example is for a any type of input (not type safe), but it can/should be adapted to specific function signatures.
package main
import (
"fmt"
"time"
)
func main() {
f := func(args ...interface{}) {
fmt.Println(args)
}
d := Debounce(f, time.Second)
for i := 0; i < 10; i++ {
d(fmt.Sprintf("%d calling", i), i, struct{}{})
time.Sleep(time.Millisecond * 10)
}
// wait for f() to run
time.Sleep(time.Minute)
}
// Debounce will group calls to the returned function into one call to f, but
// only once the returned function has stopped being called for d nanoseconds.
func Debounce(f func(args ...interface{}), d time.Duration) func(args ...interface{}) {
incoming := make(chan []interface{})
go func() {
var e []interface{}
t := time.NewTimer(d)
t.Stop()
for {
select {
case e = <-incoming:
t.Reset(d)
case <-t.C:
go f(e)
}
}
}()
return func(args ...interface{}) {
go func() { incoming <- args }()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment