什么是防抖技术
我们知道为了防止用户在短时间内高频请求后端资源导致资源匮乏且低效,我们会在前端使用“防抖技术”,将用户进行高频请求操作的请求进行一个延迟,直到用户停止该操作。
简易的防抖代码
export const debounce = (func:Function,wait:number) => {
let timer:number
return (...args:any[])=>{
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(()=>{
func(...args)
},wait)
}
}
解析该代码
学习该代码前需了解 闭包、高阶函数、Typescript(也可使用JS书写)
- 所谓的闭包即在此函数内声明的变量,会持续到return的那个函数完全执行完,才会消失,所以也会带来内存泄漏的可能性风险。在return内部的函数,由于作用域的关系,timer变量似乎便成为了该函数的全局变量。
- 高阶函数,高阶函数,即函数的参数或者返回值为一个函数。
进一步的封装
问题:在防抖之后,我想要执行一些额外的操作,应该怎么办呢?
解答
- 首先我们要直到执行的额外操作的位置,很明显,是在func(…arg)之后,于是,我们需要传入一个新的函数,即为该防抖函数的回调函数。
- 其次,计时器,是一个异步操作,所以我们要使用专门处理异步操作的Promise对象进行封装,当计时器结束,我们可以resolve(成功结束的标志),然后.then进行回调操作。
代码
export const debounce = (wait:number,func:Function,callFunc ?: Function) => {
let timer:number
return (...args:any[])=>{
if (timer) {
clearTimeout(timer)
}
new Promise((resolve,reject)=>{
timer = setTimeout(()=>{
func(...args)
resolve(1)
},wait)
}).then((resolve)=>{
if (callFunc) callFunc()
})
}
}
在项目中的使用,以vue3项目为例子
//封装两个防抖器
const cancelBtnDebounce = debounce(1000,cancelFocus,cancelThenFuc)
const focusBtnDebounce = debounce(1000,postFocusUser,focusThenFuc)
/**
* methods
* cancelFocusClick 取消关注事件
* focusClick 关注用户事件
*/
const cancelFocusClick = ()=> {
// 高阶函数的使用,传入参数
cancelBtnDebounce(props.focusList.negative)
}
const focusClick = ()=> {
focusBtnDebounce(props.focusList.negative)
}