今天在写输入提示功能的时候需要用到防抖操作,依然遇到了一些问题,于是做了总结。
防抖
作用:防止用户多次执行某个函数;具体表现为:连续【时间间隔小于某个自定义值】触发n次,只有最后一次为有效执行。
重点:转化为最后一次有效执行
常用在用户输入提示,节省网络请求次数
export const useDebounce = function debounce(func:any){
let timer :any = null
//闭包---保留这里的作用域,timer就可以做到每次执行时都能访问到
return ()=>{
clearTimeout(timer)
timer = setTimeout(() => {
func()
}, 1000);
}
}
如果想要每次触发时都传入参数,就要注意了!!并不是给useDebounce传入参数,这个hook只执行一次,每次都会执行的是回调函数【返回的函数】,所以应该给回调函数传入参数
export const useDebounce = function debounce(func:any){
let timer :any = null
//闭包---保留这里的执行上下文,timer就可以做到每次执行时都能访问到
return (text:string)=>{
clearTimeout(timer)
timer = setTimeout(() => {
func(text)
}, 1000);
}
}
节流
作用:防止用户连续执行某个函数;具体表现为:连续触发n次,有效执行m次,其中m[0]与m[1]间隔大于等于特定时间,m[1]与m[2]间隔大于等于特定时间......
重点:转化为特定时间内不允许连续执行,大于这个时间间隔后可以再次执行。
常用在滚动事件回调,鼠标点击事件回调,避免执行过于频繁,影响性能
export const useThrottle = (func:any)=>{
let timer:any = null
return (text :string)=>{
// 如果有任务,则等待
if(timer){
return
}
// 如果无任务,则计时执行
timer = setTimeout(() => {
func(text)
timer = null
}, 1000);
}
}
// 解决第一次等待的情况,立即执行
export const useThrottleDate = (func:any)=>{
let pre = 0
return ()=>{
let now = new Date()
if(+now - pre > 1000){
func() //执行就记录当前执行的时间点
pre = +now
}
}
}
总结
无论是防抖还是节流,作为hooks使用时,只执行一次,反复执行的是他返回的函数
都用到了闭包来保留执行上下文中作用域链
如果要给回调函数传参数,需要再次基础上进行修改