import { md5_hex } from "./md5" class _CommonUtil { functionReqMap = new Map() setTimeOutMap = new Map() /** * 防抖函数(调用会立即触发,在wait时间内不再触发) * @param fun 业务函数 * @param wait 等待时间(在等待时间内防止重复触发,默认1.5秒内拒绝所有数据) * 使用示例:wait可以不填写,默认1500毫秒 * CommonUtil.debounce(()=>{ * // todo * },500) */ debounce(fun, wait = 1500) { let funcValue1 = fun.toString() let hash = md5_hex(funcValue1) let startTime = Date.now() if (this.functionReqMap.get(hash)) { let funcValue = this.functionReqMap.get(hash) // 防止因为特殊原因没有移除map中该函数的记录,导致一直无法执行函数的问题 if (funcValue && funcValue.startTime + funcValue.wait <= startTime) { this.functionReqMap.delete(hash) } else { return } } this.functionReqMap.set(hash, { startTime: startTime, wait: wait }) // 执行函数调用 fun() // 拦截在wait期间的函数再次调用,在超时后,将限制解除 setTimeout(() => { let needRemoveKeys = [] this.functionReqMap.forEach((value, key, map) => { let curTime = Date.now() let funcValue = map.get(key) if (funcValue && funcValue.startTime + funcValue.wait <= curTime) { // @ts-ignore needRemoveKeys.push(key) } }) needRemoveKeys.map((value) => { this.functionReqMap.delete(value) }) }, wait) } debounceHold(fun, wait = 1500) { return this.throttle(fun, wait) } uniqueIdMap = new WeakMap() getUuid() { return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) { var r = (Math.random() * 16) | 0, v = c == "x" ? r : (r & 0x3) | 0x8 return v.toString(16) }) } getUniqueId(fun) { if (!this.uniqueIdMap.has(fun)) { this.uniqueIdMap.set(fun, this.getUuid()) } return this.uniqueIdMap.get(fun) } /** * 防抖动函数,调用后会延迟wait时间执行,当在wait时间内再次对同一函数调用,则会取消之前的定时器,重新定时 * @param fun * @param wait * @return setTimeout的句柄 */ throttle(fun, wait = 1500) { let funcValue1 = this.getUniqueId(fun) 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, { timeoutNumber: timeoutNumber, startTime: new Date().getTime() }) return timeoutNumber } /** * 取消延迟执行函数 * @param timeoutId debounceHold返回的timeout句柄 */ cancel(timeoutId) { clearTimeout(timeoutId) } } /* eslint-enable */ export const CommonUtil = new _CommonUtil()