返回

防抖节流深度剖析:7 个角度带你全面理解背后的原理

前端

在上一篇文章中,我们学习了 Lodash 中防抖和节流函数是如何实现的,并对源码进行了浅析。今天这篇文章会通过七个小例子为切入点,换种方式继续解读源码。其中源码解析上篇文章已经非常详细介绍了,这里就不再重复,建议本文配合上文一起服用,猛戳这里学习。有什么想法或者意见都可以在评论区留言,欢迎~

1. 防抖与节流的异同

防抖和节流都是用来限制函数的执行频率,防止函数被过度调用。但是,两者之间存在一些差异。

  • 防抖:防抖会在函数的最后执行一次。也就是说,当函数触发时,它会启动一个计时器。如果在计时器到期之前函数再次触发,那么计时器将被重置。只有当计时器到期时,函数才会执行。
  • 节流:节流会在函数的第一次执行后,等待一段时间再执行下一次。也就是说,当函数触发时,它会启动一个计时器。如果在计时器到期之前函数再次触发,那么函数不会执行。只有当计时器到期时,函数才会执行。

2. 防抖的应用场景

防抖通常用于以下场景:

  • 搜索框:当用户在搜索框中输入时,我们可以使用防抖来限制搜索请求的发送频率。这样可以防止服务器被过多的请求淹没。
  • 表单验证:当用户在表单中输入时,我们可以使用防抖来限制表单验证的频率。这样可以防止表单被过多的请求淹没。
  • 滚动事件:当用户滚动页面时,我们可以使用防抖来限制滚动事件的触发频率。这样可以防止浏览器被过多的事件淹没。

3. 节流的应用场景

节流通常用于以下场景:

  • 窗口大小改变事件:当窗口大小改变时,我们可以使用节流来限制窗口大小改变事件的触发频率。这样可以防止浏览器被过多的事件淹没。
  • 鼠标移动事件:当鼠标移动时,我们可以使用节流来限制鼠标移动事件的触发频率。这样可以防止浏览器被过多的事件淹没。
  • 键盘事件:当用户按键盘时,我们可以使用节流来限制键盘事件的触发频率。这样可以防止浏览器被过多的事件淹没。

4. Lodash 防抖函数的实现

Lodash 防抖函数的实现如下:

function debounce(func, wait, options) {
  let timeout, args, context, timestamp, result;

  const later = function() {
    const last = Date.now() - timestamp;

    if (last < wait && last >= 0) {
      timeout = setTimeout(later, wait - last);
    } else {
      timeout = null;
      result = func.apply(context, args);
      if (!timeout) {
        args = context = null;
      }
    }
  };

  return function() {
    context = this;
    args = arguments;
    timestamp = Date.now();
    const callNow = !timeout;
    if (!timeout) {
      timeout = setTimeout(later, wait);
    }
    if (callNow) {
      result = func.apply(context, args);
    }
    return result;
  };
}

5. Lodash 节流函数的实现

Lodash 节流函数的实现如下:

function throttle(func, wait, options) {
  let leading = true,
    trailing = true;

  if (typeof options === 'object') {
    leading = 'leading' in options ? !!options.leading : leading;
    trailing = 'trailing' in options ? !!options.trailing : trailing;
  }

  const timeout = null,
    result;

  const later = function() {
    timeout = null;
    if (!trailing) {
      result = func.apply(context, args);
    }
  };

  const throttled = function() {
    const context = this,
      args = arguments;
    if (timeout) {
      clearTimeout(timeout);
    }
    if (leading) {
      result = func.apply(context, args);
      timeout = setTimeout(later, wait);
    } else {
      timeout = setTimeout(() => {
        result = func.apply(context, args);
        timeout = null;
      }, wait);
    }
    return result;
  };

  throttled.cancel = function() {
    clearTimeout(timeout);
    timeout = null;
    leading = trailing = false;
  };

  return throttled;
}

6. 防抖和节流的性能比较

在性能方面,防抖优于节流。这是因为防抖只会在函数的最后执行一次,而节流会在函数的第一次执行后,等待一段时间再执行下一次。因此,防抖的执行次数比节流少。

7. 防抖和节流的优缺点比较

特性 防抖 节流
执行次数
性能
适用场景 搜索框、表单验证、滚动事件 窗口大小改变事件、鼠标移动事件、键盘事件

总结

本文通过七个小例子为切入点,深入剖析了 Lodash 防抖节流原理。希望这篇文章能够帮助你全面理解 Lodash 防抖节流的原理,并掌握其在实际项目中的应用技巧。如果你有任何问题,欢迎在评论区留言。