谈谈节流和防抖

403 阅读1分钟

节流

节流函数是某个函数在一段时间内,无论触发多少次都只执行一次的函数。

节流函数有两种实现方案:

  1. 用时间戳来判断是否已到执行时间;
  2. 使用定时器。
/**
 * 
 * @param {需要执行的函数} fn 
 * @param {时间间隔} wait 
 */
const throttleByTimeStamp = (fn, wait = 50) => {
  // 上一次执行 fn 的时间
  let previous = 0
  return function () {
    // 获取当前时间,转换成时间戳
    let now = +new Date()
    if (now - previous > wait) {
      // 大于等待时间
      // 执行函数
      // 把 previous 设置为当前时间
      fn.apply(this, arguments)
      previous = now
    }
  }
}

// test
const betterFn = throttleByTimeStamp(() => console.log('fn 函数执行了'), 3000)
setInterval(betterFn, 100)

/**
 * 
 * @param {需要执行的函数} fn 
 * @param {时间间隔} wait 
 */
const throttleByTimer = (fn, wait = 50) => {
  let timeout = null
  return function () {
    const context = this
    if (!timeout) {
      timeout = setTimeout(() => {
        timeout = null
        fn.apply(context, arguments)
      }, wait)
    }
  }
}

// test
const betterFn = throttleByTimer(() => console.log('fn 函数执行了'), 3000)
setInterval(betterFn, 100)

防抖

防抖函数是指某个函数在某段时间内,无论触发多少次都只执行最后一次的函数。

防抖函数的实现方式是利用定时器,函数第一次执行时设定一个定时器,之后调用时发现已经设定过定时器就清空之前的定时器,并重新设定一个新的定时器,如果存在没有被清空的定时器,当定时器计时结束后触发函数执行。

/**
 * 
 * @param {需要执行的函数} fn 
 * @param {时间间隔} wait 
 */
const debounce = (fn, wait = 50) => {
  let timer = null
  return function () {
    const context = this
    const args = arguments
    if (timer) {
      // 如果已经设定过定时器就清空上一次的定时器
      clearTimeout(timer)
    }
    // 开始设定一个新的定时器,定时器结束后执行传入的函数 fn
    timer = setTimeout(() => {
      fn.apply(context, args)
    }, wait)
  }
}