JS防抖函数支持多个函数调用

关于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()

猜你喜欢

转载自blog.csdn.net/u010899138/article/details/107337700
今日推荐