隐藏
«

防抖节流函数封装成独立组件

时间:2025-12-2 17:26     作者:suxiaojun     分类:


防抖函数

/**
 * @description 防抖函数
 * @param fn 需要防抖的方法
 * @param delay 延迟时间
 * @returns
 */
export function debounce<T extends (...args: any[]) => void>(
  fn: T,
  delay = 300
) {
  let timer: ReturnType<typeof setTimeout> | null = null

  const debounced = (...args: Parameters<T>) => {
    if (timer) clearTimeout(timer)
    timer = setTimeout(() => {
      fn(...args)
    }, delay)
  }

  debounced.cancel = () => {
    if (timer) clearTimeout(timer)
    timer = null
  }

  return debounced as T & { cancel: () => void }
}

节流函数

/**
 * 节流函数(throttle)
 * 在一定时间内,只会执行一次目标函数。
 * 适用于滚动触发、窗口缩放、按钮频繁点击等场景。
 *
 * @param func 需要执行的目标函数
 * @param wait 间隔时间(单位:毫秒)
 * @returns 返回包装后的节流函数
 */
export function throttle(func: (...args: any[]) => void, wait = 300) {
  // 记录上一次执行的时间戳
  let lastTime = 0
  // 定时器,用于 trailing 触发(可选)
  let timer: any = null

  return function (this: any, ...args: any[]) {
    const now = Date.now()

    // 如果当前时间 - 上次执行时间 >= 间隔时间,则立即执行
    if (now - lastTime >= wait) {
      lastTime = now
      func.apply(this, args)
    } else {
      // 清除之前的定时器,重新设置(保证最后一次触发会执行)
      clearTimeout(timer)
      timer = setTimeout(() => {
        lastTime = Date.now()
        func.apply(this, args)
      }, wait - (now - lastTime))
    }
  }
}

页面中使用

import { debounce } from '@/utils/debounce'
import { throttle } from '@/utils/throttle'

const handleChangeDebounce = debounce(需要防抖的Function, time)
const handleChangeThrottle = throttle(需要节流的Function, time)