前端-JavaScript防抖和节流

82 阅读2分钟

一、前言

防抖(Debounce)节流(Throttle) 都是用于控制高频率事件触发的技术。它们的主要区别在于控制函数执行的策略不同

二、防抖

  • 定义:防抖是一种策略,用于确保在事件连续触发后,只有在最后一次触发后才会执行一次。可以自定义一个时间间隔,如果在这个时间间隔内再次触发事件,计时器会被重置。

  • 行为:防抖会延迟函数的执行,直到事件不再触发为止(核心是延迟)。

  • 场景

    1、搜索框自动联想:在用户停止输入一定时间后才发送请求,避免每输入一个字符都发送请求。

    2、窗口调整:当用户调整浏览器窗口大小时,停止调整后再执行重新渲染,避免多次触发渲染。

    3、表单验证:在用户停止输入表单内容后进行验证,避免每输入一个字符都进行验证。

  • 代码

function debounce(func, wait) {
    let timeout;
    return function(...args) {
        // 每次触发事件时,先清除之前的计时器
        clearTimeout(timeout);
        // 重新设置一个新的计时器
        timeout = setTimeout(() => {
            // 改变this指向返回的函数,并传递参数
            func.apply(this, args);
        }, wait);
    };
}

三、节流

  • 定义:节流是一种策略,用于确保一个函数在规定的时间间隔内,无论触发多少次,最多只执行一次。

  • 行为:节流会限制函数的执行频率,在一个固定的时间间隔内只允许执行一次(核心是限频)。

  • 场景

    1、监听滚动条:在用户滚动页面时,每隔一段时间检查一次滚动位置,避免频繁触发。

    2、鼠标拖拽:在拖拽元素时,每隔一定时间更新一次位置,避免频繁更新造成性能问题。

    3、防止按钮重复点击:在用户点击按钮时,每隔一定时间才允许触发一次,避免频繁点击导致重复操作。

  • 代码

function throttle(func, wait) {
    let timeoutId;
    return function(...args) {
        // timeoutId 为空才能触发函数
        if (!timeoutId) {
            // 给 timeoutId 赋值,暂停触发函数 
            timeoutId = setTimeout(() => {
                // 改变this指向返回的函数,并传递参数
                func.apply(this, args);
                // 定时器达到指定时间,清空 timeoutId,使得下次可以再次触发
                timeoutId = null;
            }, wait);
        }
    };
}