面试官系列:请手写防抖或节流函数debounce/throttle

1,695 阅读2分钟

前言:

本文记录实现debounce/throttle函数,鉴于防抖和节流函数整体并不复杂,本文将直接抛出手写结果并注释说明。

温馨提示:码字不易,先赞后看,养成习惯!

相关知识:

  • es6默认参数
  • setTimeout
  • apply/call
  • 箭头函数相关

debounce (防抖)

举个例子:debounce很像上公交车,公交车入站后乘客一个一个的有序上车(类似于连续触发函数),公交车只有等最后一位乘客完成上车动作才会发车(只有最后一次触发结束后才会执行函数)

/*
 * @des                               防抖函数
 * @param  {Number}    delay          延迟时间(ms),不传默认200ms
 * @param  {Function}  callback       回调函数
 * @param  {Boolen}    false          触发时是否立即执行一次,默认不执行
 * @return {Function}                 A new debounce function
 */
const debounce = (callback, delay = 200, im = false) => {
  let timeoutID = null
  return function() {
    // 第一次触发时是否立即执行
    if (im && !timeoutID) callback.apply(this, arguments)
    // 避免开启过多计时器
    if (timeoutID) clearTimeout(timeoutID)
    timeoutID = setTimeout(() => {
      // 借用外部第一个普通函数的this和arguments对象
      callback.apply(this, arguments)
      // 执行后将timeoutID置为null
      timeoutID = null
    }, delay)
  }
}

throttle(节流)

再举个例子:throttle很像上地铁,人们在不断的上地铁(类似于连续触发函数),但是地铁不会等待最后一个人上车后再发车而是有规律的每隔几分钟发一班车(按规定时间间隔不断的执行函数)

/*
 * @des                               节流函数
 * @param  {Number}    delay          延迟时间(ms),不传默认200ms
 * @param  {Function}  callback       回调函数
 * @param  {Boolen}    false          触发时是否立即执行第一次,默认不执行
 * @return {Function}                 A new throttle function
 */
const throttle = (callback, delay = 200, im = false) => {
  let timeoutID = null
  return function() {
    // 第一次触发时是否立即执行
    if (im && !timeoutID) {
      // 立即执行
      callback.apply(this, arguments)
      // 执行后立即关闭
      im = false
    }
    if (!timeoutID) {
      timeoutID = setTimeout(() => {
        // 外部第一个普通函数this和arguments对象
        callback.apply(this, arguments)
        // 执行后将timeoutID置为null
        timeoutID = null
      }, delay)
    }
  }
}

相关文章推荐

最后

如有不明白,有疑问的欢迎拍砖!( ఠൠఠ )ノ!!!