深入理解JS函数去抖

2024-12-23 17:07:37

一. 基本定义

去抖(Debounce)是指当持续触发事件时,只在指定时间间隔内的最后一次触发生效。其他期间的触发会被忽略。这通常用于搜索框输入时,用户停止输入一段时间后开始搜索,防止因为用户的快速输入导致不必要的资源消耗。

在JavaScript中,可以使用定时器(setTimeout)来实现去抖功能。

二. 自定义函数

在 JavaScript 中,创建自定义的 debounce 函数是一个非常常见的需求,特别是为了优化高频触发事件的性能。以下是如何实现一个自定义的 debounce 函数,以及对其工作原理的详细解释。

1. 自定义 debounce 函数

function debounce(func, delay = 500) {
  let timeoutId; // 存储定时器ID

  return function (...args) {
    // 清除之前的定时器
    if (timeoutId) {
      clearTimeout(timeoutId);
    }

    // 设置新的定时器,延迟执行原始函数
    timeoutId = setTimeout(() => {
      func(...args);
    }, delay);
  };
}

解释:

timeoutId: 我们用 timeoutId 来保存每次 setTimeout 返回的定时器 ID,这样就可以在触发新事件时取消掉之前的定时器。

clearTimeout(timeoutId): 如果事件被触发(例如用户不断输入或滚动),我们通过 clearTimeout 来取消上一个定时器,防止不必要的执行。

setTimeout: 每次事件触发时,我们会设置一个新的定时器,并在指定的延迟时间后执行目标函数(func)。只有当事件不再频繁触发超过指定的延迟时间时,函数才会被执行。

args: 使用 ...args 来确保我们传递给 debounced 函数的所有参数都会被传递到目标函数 func 中。

使用示例:

假设我们有一个输入框,并希望每次用户输入时只在用户停止输入 500 毫秒后才执行搜索函数。

// 假设这是我们的输入事件处理函数
function handleSearch(event) {
  console.log("Searching for:", event.target.value);
}

// 创建一个防抖版本的 handleSearch 函数
const debouncedSearch = debounce(handleSearch, 500);

// 绑定到输入框的 input 事件
const inputElement = document.querySelector("input");
inputElement.addEventListener("input", debouncedSearch);

在这个示例中,用户每次输入时,debouncedSearch 会被触发。debounce 会确保只有用户停止输入超过 500 毫秒时,handleSearch 函数才会真正执行,从而减少了过多的搜索请求。

2. 更多自定义选项

你可以根据需要扩展 debounce 函数,加入更多的功能,例如:

  • 立即执行: 如果你希望在事件发生的第一次时就立即执行函数,可以增加一个选项来控制这一行为。

  • 取消功能: 提供一个方法来取消防抖定时器,以便手动停止防抖函数的执行。

扩展:立即执行和取消功能

function debounce(func, delay, immediate = false) {
  let timeoutId;

  return function (...args) {
    if (timeoutId) {
      clearTimeout(timeoutId);
    }

    if (immediate && !timeoutId) {
      // 如果 immediate 为 true 且没有正在等待的定时器,则立即执行一次
      func(...args);
    }

    timeoutId = setTimeout(() => {
      if (!immediate) {
        func(...args); // 延迟执行原始函数
      }
    }, delay);
  };
}

使用示例:

立即执行: 如果设置 immediate 为 true,则在第一次触发事件时立即执行 func,之后才会等待 delay 时间。

const debouncedSearch = debounce(handleSearch, 500, true); // 立即执行

取消功能: 你可以通过返回的 debounced 函数来清除定时器,以停止进一步的执行。

const debouncedSearch = debounce(handleSearch, 500);

// 调用 debounce 函数
debouncedSearch(event);

// 取消防抖功能
debouncedSearch.cancel = () => clearTimeout(debouncedSearch.timeoutId);

// 手动取消防抖
debouncedSearch.cancel();

三. 总结

Debounce 适用于防止在快速连续触发的事件中,执行昂贵操作(如 API 请求、DOM 操作等)。

自定义实现 让你能够根据自己的需求,精细控制防抖行为(例如延迟时间、是否立即执行等)。

扩展功能 可以根据需求增加如立即执行、取消等高级特性。

通过这种方式,你可以确保你的应用在性能上得到优化,同时提升用户体验。

目录

相关推荐
JavaScript之 in 运算符及其应用对象属性描述对象-JavaScript浅析 URLSearchParams 使用详细介绍JavaScript中的深拷贝、浅拷贝