Golang模拟实现防抖与节流效果
在Golang实现了js中setTimeout与setInterval后我们可以通过setTimeout来实现js中防抖与节流的效果
一、介绍
防抖函数:单位时间内连续触发的事件,但是只在最后一次出发后开始计算执行一次
节流函数:一段时间内无论触发多少次到时间后只执行一次
二、防抖函数
func Debounce(f func(), wait int) func() {
var cf context.CancelFunc
return func() {
if cf != nil {
cf()
}
cf = SetTimeout(f, wait)
}
}
三、节流函数
func Throttled(f func(), wait int) func() {
var cf context.CancelFunc
return func() {
if cf == nil {
cf = SetTimeout(f, wait)
}
}
}
四、完整测试
package main
import (
"context"
"fmt"
"os"
"time"
)
func main() {
// 测试防抖是通过for循环定时3秒(保证在防抖函数触发前)连续触发五次,保证输出`testDebounce`只在最后一次开始计算
// testDebounce()
// 测试节流是通过for循环定时3秒连续触发五次,保证输出`testThrottled`只在指定时间内不受触发次数影响
// testThrottled()
}
func testDebounce() {
f := Debounce(func() {
fmt.Println("testDebounce")
os.Exit(0)
}, 5)
for i := 0; i < 5; i++ {
f()
time.Sleep(3 * time.Second)
}
time.Sleep(100 * time.Second)
}
func testThrottled() {
f := Throttled(func() {
fmt.Println("testThrottled")
os.Exit(0)
}, 5)
for i := 0; i < 5; i++ {
f()
time.Sleep(3 * time.Second)
}
time.Sleep(100 * time.Second)
}
func Debounce(f func(), wait int) func() {
var cf context.CancelFunc
return func() {
if cf != nil {
cf()
}
cf = SetTimeout(f, wait)
}
}
func Throttled(f func(), wait int) func() {
var cf context.CancelFunc
return func() {
if cf == nil {
cf = SetTimeout(f, wait)
}
}
}
func SetTimeout(f func(), timeout int) context.CancelFunc {
ctx, cancelFunc := context.WithCancel(context.Background())
go func() {
select {
case <-ctx.Done():
case <-time.After(time.Duration(timeout) * time.Second):
f()
}
}()
return cancelFunc
}
func SetInterval(f func(), timeout int) context.CancelFunc {
ctx, cancelFunc := context.WithCancel(context.Background())
go func() {
for {
time.Sleep(time.Duration(timeout) * time.Second)
select {
case <-ctx.Done():
return
default:
f()
}
}
}()
return cancelFunc
}