typescript 中函数防抖与节流的装饰器

473 阅读1分钟

防抖

/**
 * 函数防抖 装饰器
 * @param _wait 防抖时间
 * @param _immediate 是否立即执行
 * @returns 防抖封装函数
 */
export function Debounce(
  _wait?: boolean | number,
  _immediate?: boolean,
): MethodDecorator {
  return function (
    target: any,
    key: string | symbol,
    desc: PropertyDescriptor,
  ) {
    const DEFAULT_TIME = 300
    if (typeof _wait === 'undefined') {
      _wait = DEFAULT_TIME
      _immediate = false
    }
    if (typeof _wait === 'boolean') {
      _immediate = _wait
      _wait = DEFAULT_TIME
    }
    if (typeof _immediate === 'undefined') {
      _immediate = false
    }
    const fn = desc.value
    let timer: any
    desc.value = function (...args: any[]) {
      clearTimeout(timer)
      const flag = _immediate && !timer
      timer = setTimeout(() => {
        timer = null
        !_immediate && fn.call(this, ...args)
      }, _wait as number)
      flag && fn.call(this, ...args)
    }
    return desc
  }
}


节流


/**
 * 节流装饰器
 * @param _wait 默认时间
 * @returns 节流封装函数
 */
export function Throttle(_wait = 600): MethodDecorator {
  return function (
    target: any,
    key: string | symbol,
    desc: PropertyDescriptor,
  ) {
    const fn = desc.value
    let previous = 0
    let timer: any
    desc.value = function (...arg: any[]) {
      const now = new Date().getTime()
      const interval = _wait - (now - previous)
      if (interval <= 0) {
        fn.apply(this, arg)
        previous = new Date().getTime()
        clearTimeout(timer)
        timer = null
      } else if (!timer) {
        timer = setTimeout(() => {
          fn.apply(this, arg)
          clearTimeout(timer)
          timer = null
        }, interval)
      }
    }
    return desc
  }
}