12.函数防抖,函数节流

书诚小驿2024/10/01前端面经JavaScript

一、函数防抖

1、什么是函数防抖

  • 事件触发后,等待一段时间(延迟)。若在等待期间再次触发事件,则重新计时。

  • 只有最后一次触发生效,之前的触发均被取消。

2、函数防抖代码实现

  • immediate = false,则每次在 delay 后执行一次函数,首次不会执行
  • immediate = true,则首次触发立即执行,之后在 delay 后执行一次函数
function debounce(func, delay, immediate = false) {
  // 闭包保存的定时器标识
  let timer;
  // 返回防抖处理后的函数(接收任意参数)
  return function (...args) {
    const that = this;
    const callNow = immediate && !timer; // 判断是否满足"立即执行"条件

    clearTimeout(timer); //  每次触发都先清除之前的定时器
    timer = setTimeout(() => {
      timer = null;
      // 若非立即执行模式,则在延迟后调用目标函数
      if (!immediate) {
        // 确保正确的 this 和参数传递
        func.apply(that, args);
      }
    }, delay);
    // 如果满足立即执行条件,则立即调用目标函数
    if (callNow) func.apply(that, args);
  };
}

二、函数节流

1、什么是函数节流

  • 无论事件触发多频繁,固定时间间隔内只执行一次函数。

  • 稀释函数的执行频率,保证周期性调用。

2、函数节流代码实现

// 时间戳版本(立即执行首次)
function throttle(func, delay) {
  let lastTime = 0;
  return function (...args) {
    const now = Date.now();
    if (now - lastTime >= delay) {
      func.apply(this, args);
      lastTime = now;
    }
  };
}

// 定时器版本(延迟执行首次)
function throttle(func, delay) {
  let timer = null;
  return function (...args) {
    if (!timer) {
      timer = setTimeout(() => {
        func.apply(this, args);
        timer = null;
      }, delay);
    }
  };
}

三、应用场景

场景技术方案原因
列表页滚动加载更多节流需要周期性触发(如每 500ms),保证加载节奏,避免遗漏中间滚动位置。
搜索框输入联想防抖用户停止输入后才请求结果,避免无效中间请求(如输入“abc”时只查“abc”)。
按钮防重复提交防抖(立即执行) 或 节流根据需求选择:立即执行首次点击,屏蔽后续点击(防抖 + immediate=true)。固定间隔内只允许提交一次(节流)。
窗口大小调整布局计算防抖调整结束后计算一次布局,避免频繁重绘。
游戏角色移动控制节流限制高频按键响应频率,保证操作流畅性(如每 100ms 响应一次方向键)。
最后更新时间' 2025/3/9 18:24:05