节流防抖

TIP

  • 节流:一段时间内只执行一次。适用于轮播图、高频点击等场景。
  • 防抖:只执行最后一次。适用于输入校验、搜索联想等场景。

WARNING

节流还可深入,防抖最大等待时间待研究。
有时间研究下 lodash 的实现。

节流

function throttle(fn, wait) {
  let timer

  return function(...args) {
    if(timer) return

    fn.apply(this, args)
    timer = setTimeout(() => timer = null, wait)
  }
}

防抖

初版

  • 回调函数、延时时间
function debounce(fn, wait) {
  let timer

  return function() {
    timer && clearTimeout(timer)
    timer = setTimeout(fn, wait)
  }
}

二版 重点

  • 回调函数、延时时间
  • this 绑定、参数绑定
function debounce(fn, wait) {
  let timer

  return function(...args) {
    timer && clearTimeout(timer)
    timer = setTimeout(() => fn.apply(this, args), wait)
  }
}

三版 重点

  • 回调函数、延时时间
  • this 绑定、参数绑定
  • immediate 立即执行
function debounce(fn, wait, immediate) {
  let timer

  return function(...args) {
    timer && clearTimeout(timer)

    if(immediate) {
      !timer && fn.apply(this, args)
      timer = setTimeout(() => timer = null, wait)
    } else {
      timer = setTimeout(() => fn.apply(this, args), wait)
    }
  }
  
}

四版

  • 回调函数、延时时间
  • this 绑定、参数绑定
  • immediate 立即执行
  • 返回值、取消防抖
function debounce(fn, wait, immediate) {
  let timer 
  let result
  
  const debounced = function(...args) {
    timer && clearTimeout(timer)
    
    if(immediate) {
      if(!timer) result = fn.apply(this, args) 
      timer = setTimeout(() => timer = null, wait)
    } else {
      timer = setTimeout(() => fn.apply(this, args), wait)
    }
    
    return result
  }
  
  debounced.cancel = function() {
    timer && clearTimeout(timer)
    timer = null
  }
  
  return debounced
}

参考

Last Updated:
Contributors: Vsnoy