防抖(Debounce)和节流(Throttle)的使用说明

21 min read

防抖(Debounce)和节流(Throttle)是两种控制函数执行频率的技术,它们在不同的应用场景中非常有用,特别是在处理那些由于用户操作或其他条件频繁触发的事件时。下面我将分别解释它们的应用场景和为什么在这些场景中使用它们是有益的。

防抖(Debounce)

应用场景

  1. 输入验证:当用户在一个输入字段中输入文本(例如搜索框或邮箱验证)时,你可能需要在用户停止输入后才进行验证或显示搜索结果。使用防抖可以等待用户完成输入,避免每次键入都触发事件。

  2. 调整窗口大小(resize):浏览器窗口大小调整时,可能需要重新计算和渲染页面布局。由于 resize 事件可能非常频繁,使用防抖可以减少计算和渲染次数,只在用户完成调整大小后执行。

  3. 按钮提交防重复点击:防止用户快速连续点击提交按钮造成的多次提交。

为什么这样用

  • 防抖技术的核心是“延迟执行”。在上述场景中,只有在触发事件后的一段时间内没有再次触发该事件时,才需要执行函数。这样做可以减少不必要的函数调用,提高性能,尤其是在涉及到复杂计算或外部资源请求的情况下。

节流(Throttle)

应用场景

  1. 滚动事件监听:例如,在滚动事件中实现无限滚动加载或滚动监听导航栏变化。由于滚动事件可能非常频繁,使用节流可以确保在指定的时间间隔内只触发一次。

  2. 实时搜索(降低请求频率):在用户输入搜索词时,如果每次输入都发送请求,可能会产生大量的请求。使用节流可以限制请求的频率。

  3. 游戏或动画中的速率限制:在需要控制动画或动作的更新频率时,节流可以保证在给定时间内只执行一次,从而保持一致的更新速率。

为什么这样用

  • 节流技术的关键是“定期执行”。它确保在固定的时间间隔内最多只执行一次函数。这在需要限制某些操作的频率时非常有用,如处理高频率触发的事件(如滚动、鼠标移动等),同时避免过多的性能开销。
export function debounce(fn: any, delay = 500) {
    let timer: any;
    return function (...args: any) {
        if (timer) {
            clearTimeout(timer);
        }
        timer = setTimeout(() => {
            fn(...args);
        }, delay);
    };
}

// 节流
export function throttle(fn: any, delay = 500) {
    let inThrottle;
    return function (...args: any) {
        if (inThrottle) {
            return;
        }
        inThrottle = true;
        fn(...args);
        setTimeout(() => {
            fn(...args);
            inThrottle = false;
        }, delay);
    };
}

总结

  • 防抖用于确保函数在一系列连续的事件触发中只在最后一次执行,适用于关注“完成触发”的场景。
  • 节流用于在连续的事件触发中按固定时间间隔执行,适用于需要“限制执行频率”的场景。

使用防抖和节流可以显著提高应用性能,尤其是在涉及复杂处理或大量数据的情况下。通过减少不必要的计算和资源请求,这些技术帮助确保应用程序的流畅运行和用户体验的优化。