前端面试题:节流与防抖(Throttle & Debounce)详解

1,344 阅读3分钟

在前端开发中,节流(Throttle)和防抖(Debounce)是两个常用的优化技术,特别是在处理频繁触发的事件时(如滚动、输入框输入等)。这两个概念看似相似,但它们的使用场景和行为有所不同。本文将详细介绍它们的区别、实现方式以及适用场景。

一、节流(Throttle)

1.1 定义

节流是一种控制函数执行频率的技术。它的核心思想是:无论事件触发的频率有多高,节流会规定一个固定的时间间隔,确保函数在这个时间间隔内只会被执行一次。

1.2 使用场景

节流适用于那些频繁触发的事件,比如:

  • 页面滚动事件
  • 调整窗口大小
  • 按钮点击

1.3 示例

// 节流函数实现
function throttle(fn, wait) {
  let lastTime = 0;
  return function() {
    const now = new Date().getTime();
    if (now - lastTime >= wait) {
      fn();
      lastTime = now;
    }
  }
}

// 使用示例
const handleScroll = throttle(function() {
  console.log('滚动事件触发');
}, 1000);

window.addEventListener('scroll', handleScroll);

在上面的代码中,throttle 函数确保 handleScroll 在每 1000 毫秒内只会执行一次,即使用户滚动页面的速度非常快。

1.4 原理

节流函数通过设置时间戳 lastTime 来记录上次执行的时间,当当前时间与上次执行时间的差值超过设定的 wait 间隔时,才会执行目标函数。


二、防抖(Debounce)

2.1 定义

防抖是一种限制函数频繁执行的技术。它的核心思想是:当事件被连续触发时,只有在事件触发停止后的特定延迟时间才会执行目标函数。如果事件在延迟时间内再次触发,之前的执行将被取消,重新计时。

2.2 使用场景

防抖常用于以下场景:

  • 输入框的实时搜索(防止每输入一个字符就发送请求)
  • 按钮的点击防抖(防止多次点击)
  • 表单提交的防抖

2.3 示例

javascriptCopy Code
// 防抖函数实现
function debounce(fn, delay) {
  let timer = null;
  return function() {
    const context = this;
    const args = arguments;
    clearTimeout(timer);
    timer = setTimeout(function() {
      fn.apply(context, args);
    }, delay);
  }
}

// 使用示例
const handleInput = debounce(function() {
  console.log('输入框事件触发');
}, 500);

document.getElementById('search-input').addEventListener('input', handleInput);

在上面的代码中,debounce 确保 handleInput 函数只有在用户停止输入 500 毫秒后才会被触发,避免了每输入一个字符都触发事件的情况。

2.4 原理

防抖函数通过 setTimeoutclearTimeout 实现。每次事件触发时都会清除之前的定时器,重新设置新的定时器,只有在设定的延迟时间内没有触发新的事件时,目标函数才会被调用。


三、节流与防抖的区别

特性节流(Throttle)防抖(Debounce)
执行频率在规定时间间隔内执行一次只有在停止触发事件后延迟一段时间执行一次
适用场景滚动、窗口大小调整等频繁触发的事件输入框搜索、按钮点击等需要延迟处理的事件
触发条件每隔一定时间触发一次事件触发停止后,延迟一定时间触发一次
实现方式利用时间戳或定时器控制执行间隔利用定时器清除和重新设置触发延迟

四、总结

  • 节流 适用于需要控制事件频率的场景,确保某个操作在固定时间内不被频繁执行。
  • 防抖 适用于需要延迟处理的场景,防止事件触发时多次执行函数。