返回

JS 防抖和节流:一劳永逸解决函数连续触发问题

前端

防抖与节流的区别

防抖和节流都是用来解决函数连续触发的问题,但它们的工作方式不同。

  • 防抖 :防抖会延迟函数的执行,直到一段时间内没有新的调用发生。如果在延迟期间有新的调用发生,则重置延迟计时器。这确保了函数只会被执行一次,即使它被连续触发多次。

  • 节流 :节流会限制函数在一段时间内只能执行一次。如果在限制期间有新的调用发生,则会被忽略。这确保了函数在一段时间内只会被执行一次,即使它被连续触发多次。

如何实现防抖和节流

防抖和节流都可以通过 JavaScript 实现。以下是两种实现方式:

1. 使用 setTimeout() 实现

这是最简单的方法来实现防抖和节流。

// 防抖
function debounce(func, delay) {
  let timer;
  return function() {
    const args = arguments;
    if (timer) {
      clearTimeout(timer);
    }
    timer = setTimeout(() => {
      func.apply(this, args);
    }, delay);
  };
}

// 节流
function throttle(func, delay) {
  let timer;
  return function() {
    const args = arguments;
    if (!timer) {
      func.apply(this, args);
      timer = setTimeout(() => {
        timer = null;
      }, delay);
    }
  };
}

2. 使用 requestAnimationFrame() 实现

requestAnimationFrame() 是一个高性能的 API,它可以让你在浏览器刷新之前执行动画。它也可以用来实现防抖和节流。

// 防抖
function debounce(func, delay) {
  let requestId;
  return function() {
    const args = arguments;
    if (requestId) {
      cancelAnimationFrame(requestId);
    }
    requestId = requestAnimationFrame(() => {
      func.apply(this, args);
    });
  };
}

// 节流
function throttle(func, delay) {
  let requestId;
  return function() {
    const args = arguments;
    if (!requestId) {
      func.apply(this, args);
      requestId = requestAnimationFrame(() => {
        requestId = null;
      });
    }
  };
}

防抖和节流的立即执行和非立即执行

防抖和节流都可以实现立即执行和非立即执行。

  • 立即执行 :这意味着函数在第一次调用时立即执行,然后按照防抖或节流的规则继续执行。

  • 非立即执行 :这意味着函数在第一次调用时不会立即执行,而是按照防抖或节流的规则延迟执行。

如何选择防抖或节流

防抖和节流都是有用的技术,但它们适用于不同的情况。

  • 防抖 适用于那些需要在用户停止操作后执行的函数,例如搜索框中的自动完成功能。

  • 节流 适用于那些需要在一定时间内只执行一次的函数,例如滚动事件中的页面加载更多功能。

总结

防抖和节流都是解决函数连续触发问题的有效技术。它们可以帮助我们提高前端应用的性能和用户体验。