关于js的防抖,业界有lodash函数工具库可以参考,也有很多同学提供了setTimeout的方式进行处理。不过就工具类是否使用以及使用哪一方的,都和个人以及团队的喜好相关,我们更关注其原理而非工具本身。
本文根据setTimeout的机制进行了调整,用以适用在公司项目开发中,提供以下方法
说明:md5_hex方式是md5算法对数据进行hash,可以自行下载https://download.csdn.net/download/u010899138/12614308
1.debounce函数
立即执行,适用于页面进入后立即加载数据,在wait时间内,fun的调用不会再执行
调用示例
// 默认执行后,在1500毫秒内再次执行只会输出一次debounce
CommonUtil.debounce(
() => {
console.log('debounce')
}
)
// 第二次调用,只会有一个debounce执行
CommonUtil.debounce(
() => {
console.log('debounce')
}
)
1.debounce函数
等待wait时间后,执行fun的调用,适用于输入框输入自动获取结果的场景
在wait时间内再次执行,会重置wait的等待时间
调用示例
// 默认在1500毫秒后输出debounce
CommonUtil.debounce(
() => {
console.log('debounce')
}
)
// 在2000秒后输出debounce
CommonUtil. debounce(
() => {
console.log('debounce')
}
,2000)
3.cancel函数
针对debounceHold函数,当需要取消fun的执行,可以调用这个方法
// 在2000秒后输出debounce
let timeoutNumber=CommonUtil.debounce(
() => {
console.log('debounce')
}
,2000)
// 取消执行
CommonUtil.cancel(timeoutNumber)
函数实现
/**
* 说明:md5_hex函数是对函数体进行md5编码,作为key记录在map中,后续在移除fun时进行比对,
* 在使用的时候,可以自行实现hash,也可以忽略,直接使用函数体的string作为key
*/
import {md5_hex} from './md5.js'
class _CommonUtil {
setTimeOutMap: Map<string, {
startTime: number,//调用的时间
timeoutNumber: number, //setTimeout的句柄
}> = new Map()
/**
* 防抖动函数,调用后会延迟wait时间执行,当在wait时间内再次对同一函数调用,则会取消之前的定时器,重新定时
* @param fun
* @param wait
* @return setTimeout的句柄
*/
debounce(fun: Function, wait: number = 1500): number {
let funcValue1 = fun.toString()
let hash = md5_hex(funcValue1)
if (this.setTimeOutMap.get(hash)) {
clearTimeout(this.setTimeOutMap.get(hash)?.timeoutNumber)
this.setTimeOutMap.delete(hash)
}
// this.checkTimeOutNumber()
let timeoutNumber = setTimeout(() => {
this.setTimeOutMap.get(hash) && clearTimeout(this.setTimeOutMap.get(hash)?.timeoutNumber)
this.setTimeOutMap.delete(hash)
// 执行函数调用
fun()
}, wait)
this.setTimeOutMap.set(hash, {
// @ts-ignore
timeoutNumber: timeoutNumber,
startTime: new Date().getTime(),
})
// @ts-ignore
return timeoutNumber
}
/**
* 取消延迟执行函数
* @param number debounce返回的timeout句柄
*/
cancel(timeoutNumber: number) {
clearTimeout(timeoutNumber)
}
}
export const CommonUtil = new _CommonUtil()