如何实现一个防抖函数?

推荐答案

-- -------------------- ---- -------
-------- -------------- ------ -
  --- --------
  ------ ----------------- -
    ----------------------
    ------- - ------------- -- -
      ---------------- ------
    -- -------
  --
-

本题详细解读

防抖函数的核心概念

防抖 (Debounce) 是一种常用的优化技巧,用于限制某个函数在短时间内被频繁调用的次数。其核心思想是:将多次触发合并成一次执行。如果持续触发事件,在设定的延迟时间内没有再次触发,则执行函数;如果在延迟时间内再次触发,则重新计时。常见应用场景包括:

  • 输入框搜索提示: 当用户在输入框输入时,不立即发送请求,而是等待用户停止输入一段时间后再发送请求,减少服务器压力。
  • 窗口resize事件: 避免窗口频繁调整大小时,导致处理函数被多次调用,造成性能问题。
  • 按钮点击: 防止用户快速多次点击按钮,产生意外操作。

代码详解

  1. 闭包: debounce 函数返回一个内部函数,形成闭包,使得timerId变量在内部函数中能够被保留和修改。

  2. timerId 变量: 用于存储 setTimeout 返回的定时器 ID,以便清除之前的定时器。

  3. return function(...args): 返回的内部函数是实际被调用的函数,接收任意数量的参数 ...args

  4. clearTimeout(timerId): 每次触发事件时,先清除之前的定时器,确保只有一个定时器在运行。

  5. setTimeout(() => { ... }, delay): 设置一个新的定时器。当延迟时间 delay 结束后,执行传入的函数 func

  6. func.apply(this, args): 使用 apply 方法调用传入的函数,并传递正确的 this 上下文和参数。

使用示例

-- -------------------- ---- -------
-------- ------------------ -
    -------------------- -------
-

----- -------------------- - --------------------- ----- -- -- --- --

-- ------
--------------------------
---------------------------
------------- -- -
    ----------------------------
-- ----- -- - ----- ---
------------- -- -
  -----------------------------
-- ---- -- - ----- ---
------------- -- -
  ------------------------------
-- ---- -- - ----- ---

-- --------------------- ----- ----

防抖和节流的区别

防抖和节流都是为了优化频繁触发的事件,但其实现方式和应用场景有所不同:

  • 防抖 (Debounce): 只在最后一次触发事件后延迟执行。如果持续触发,则重新计时。适用于只需要最后一次触发结果的场景,如输入框搜索。
  • 节流 (Throttle): 在一段时间内,只执行一次函数。适用于需要控制函数执行频率的场景,如滚动事件。

扩展:带有立即执行的防抖函数

-- -------------------- ---- -------
-------- -------------- ------ --------- - ------ -
    --- --------
    --- ------- - ------
    ------ ----------------- -
        ------------ -- --------- -
          ---------------- ------
          ------- - -----
        -
        ----------------------
        ------- - ------------- -- -
            -- ----------- -- ---------
               ---------------- ------
            -
            ------- - -----
            ------- - ------
        -- -------
    --
-

通过添加 immediate 参数,可以实现立即执行的版本。当 immediatetrue 时,在第一次触发事件时会立即执行函数,之后才会进行防抖延迟,并且只有在定时器时间结束后才会再次执行。

纠错
反馈