Last active
July 25, 2022 09:25
-
-
Save leolara/d62b87797b0ef5e418cd to your computer and use it in GitHub Desktop.
Golang port of underscore.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
func debounceChannel(interval time.Duration, output chan int) chan int { | |
input := make(chan int) | |
go func() { | |
var buffer int | |
var ok bool | |
// We do not start waiting for interval until called at least once | |
buffer, ok = <-input | |
// If channel closed exit, we could also close output | |
if !ok { | |
return | |
} | |
// We start waiting for an interval | |
for { | |
select { | |
case buffer, ok = <-input: | |
// If channel closed exit, we could also close output | |
if !ok { | |
return | |
} | |
case <-time.After(interval): | |
// Interval has passed and we have data, so send it | |
output <- buffer | |
// Wait for data again before starting waiting for an interval | |
buffer, ok = <-input | |
if !ok { | |
return | |
} | |
// If channel is not closed we have more data and start waiting for interval | |
} | |
} | |
}() | |
return input | |
} |
func debounce(interval time.Duration, f func()) func() {
var timer *time.Timer
var v atomic.Value
v.Store(timer)
return func() {
swapped := v.CompareAndSwap((*time.Timer)(nil), time.NewTimer(interval))
if swapped {
go func() {
timerr := (v.Load()).(*time.Timer)
<-timerr.C
timerr.Stop()
v.Store((*time.Timer)(nil))
f()
}()
} else {
return
}
}
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
No timers or channels solution, that uses power of atomics: