实现一个防抖和节流函数,使用ts

说明

防抖和节流都是为了限制函数的执行频率,但是它们的实现方式和效果略有不同。

防抖

防抖函数会在函数被调用后,等待一段时间(例如 500 毫秒),如果在这段时间内没有再次调用该函数,则执行该函数。如果在等待时间内又调用了该函数,则重新计时。这样可以避免在短时间内频繁触发函数,从而减少不必要的计算和网络请求。

防抖的应用场景:

  • 搜索框输入联想:用户输入内容时,等待一段时间后再发送请求,避免频繁发送请求。
  • 窗口大小改变事件:用户调整窗口大小时,等待一段时间后再重新计算布局,避免频繁计算布局。

节流

节流函数会在函数被调用后,等待一段时间(例如 500 毫秒),只要在这段时间内再次调用该函数,就会忽略该调用。直到等待时间过去后,才会再次执行该函数。这样可以确保在一段时间内只执行一次函数,从而减少不必要的计算和网络请求。

节流的应用场景:

  • 滚动事件:用户滚动页面时,等待一段时间后再执行相关操作,避免频繁触发事件。
  • 鼠标移动事件:用户移动鼠标时,等待一段时间后再执行相关操作,避免频繁触发事件。

综上所述,防抖和节流都是为了限制函数的执行频率,但是它们的实现方式和应用场景略有不同,需要根据具体的业务需求来选择适合的函数。

函数

防抖函数

/**
 * 防抖函数
 * @param {Function} func 要执行的函数
 * @param {number} wait 等待时间(毫秒)
 * @param {boolean} immediate 是否立即执行
 * @returns {Function} 返回一个新的函数
 */
function debounce<T extends Function>(func: T, wait: number = 500, immediate: boolean = false): (...args: any[]) => void {
  let timeout: ReturnType<typeof setTimeout> | null;
  return function debounced(this: any, ...args: any[]) {
    const context = this;
    const later = function() {
      timeout = null;
      if (!immediate) func.apply(context, args);
    };
    const callNow = immediate && !timeout;
    clearTimeout(timeout as ReturnType<typeof setTimeout>);
    timeout = setTimeout(later, wait);
    if (callNow) func.apply(context, args);
  };
}

节流函数

/**
 * 节流函数
 * @param {Function} func 要执行的函数
 * @param {number} wait 等待时间(毫秒)
 * @returns {Function} 返回一个新的函数
 */
function throttle<T extends Function>(func: T, wait: number = 500): (...args: any[]) => void {
  let timeout: ReturnType<typeof setTimeout> | null;
  return function throttled(this: any, ...args: any[]) {
    const context = this;
    if (!timeout) {
      timeout = setTimeout(function() {
        func.apply(context, args);
        timeout = null;
      }, wait);
    }
  };
}

在上面的示例中,我们使用了 TypeScript 的泛型和类型注解,以及箭头函数的语法来实现防抖和节流函数。其中,泛型 T 表示函数类型,类型注解 : T 表示返回值的类型是函数类型 T。类型注解 : any[] 表示参数的类型是任意类型的数组。在函数体内,我们使用了 this: any 来指定函数的上下文为任意类型,避免了 TypeScript 的类型检查错误。