节流和防抖

219 阅读1分钟
原文链接: 0jinxing.github.io

debounce(防抖)和 throttle(节流)是函数延迟执行的两种相似的(但是不同)策略,

下面的两段注释来自 lodash,就能比较好的说明问题。

函数防抖 debounce

/**
 * Creates a debounced function that delays invoking `func` until after `wait`
 * milliseconds have elapsed since the last time the debounced function was
 * invoked, or until the next browser frame is drawn.
 *
 * @example
 * // Avoid costly calculations while the window size is in flux.
 * // Invoke `sendMail` when clicked, debouncing subsequent calls.
 * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
 * // Cancel the trailing debounced invocation.
 *
 */

函数节流 throttle

/**
* Creates a throttled function that only invokes `func` at most once per
* every `wait` milliseconds (or once per browser frame). 
*
* @example
* // Avoid excessively updating the position while scrolling.
* // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
*
*/

debounce 的简单实现

function debounce(fn, wait) {
    let timer = 0;
    return () => {
        if (!!timer) clearTimeout(timer);
        timer = setTimeout(() => fn.apply(this, arguments), wait);
    };
}

throttle 的简单实现

function throttle(fn, delay) {
    let timer = 0;
    let lastInvokeTime = 0;
    return () => {
        if (+new Date() - lastInvokeTime <= delay) return;

        clearTimeout(timer);
        lastInvokeTime = +new Date()
        timer = setTimeout(() => fn.apply(this, arguments), delay);
    }
}

需要注意的是由于浏览器端 JavaScript 的运行机制,debouncethrottle 的执行时间可能存在一定的延迟

参考:

  1. css-tricks.com/debouncing-…
  2. github.com/lodash/loda…
  3. github.com/lishengzxc/…