跳至主要內容

10. 函数防抖

鸭梨小于 1 分钟

10. 函数防抖

对指定函数进行处理,使得函数 NN 秒后执行且只会执行一次,如果 NN 秒内事件再次触发,则会重新计时。

 * @param {number} wait
 */
function debounce(func, wait) {
  let timeout
  return function () {
    const context = this
    const args = arguments
    clearTimeout(timeout)
    timeout = setTimeout(() => {
      func.apply(context, args)
    }, wait)

测试代码:

}

const node = document.getElementById('layout')
function getUserAction(e) {
  console.log(this, e)
  node.innerHTML = count++
};

最终版:除了支持 thisevent 外,还支持以下功能:

  • 支持立即执行
  • 函数可能有返回值
  • 支持取消功能
/* eslint-disable ts/no-this-alias */
/* eslint-disable prefer-rest-params */
export function debounce(func, wait, immediate) {
  let timeout, result
  const debounced = function () {
    const context = this
    const args = arguments

    if (timeout)
      clearTimeout(timeout)
    if (immediate) {
      // 如果已经执行过,不再执行
      const callNow = !timeout
      timeout = setTimeout(() => {
        timeout = null
      }, wait)
      if (callNow)
        result = func.apply(context, args)
    }
    else {
      timeout = setTimeout(() => {
        func.apply(context, args)
      }, wait)
    }
    return result
  }

  debounced.cancel = function () {
    clearTimeout(timeout)
    timeout = null
  }

  return debounced
}