面试题:JS中的节流与防抖(2)

264 阅读4分钟

image.png

节流(Throttling)和防抖(Debouncing)是JavaScript中常用的两种优化技术,用于限制函数的执行频率,提高应用的性能和响应速度。它们在处理频繁触发的事件(如滚动、窗口调整大小、键盘输入等)时特别有用。

定义

节流(Throttling)

一定时间内只执行一次事件,在一段时间intervalTime内,不管触发了多少次事件(大于1)都只执行一次。

工作原理

  • 时间间隔:设置一个固定的时间间隔(例如100毫秒)。
  • 函数执行:在每个时间间隔内,无论事件触发多少次,函数只执行一次。

image.png

示例:节流

function throttle(func, limit) {
    let inThrottle;
    return function() {
        const args = arguments;
        const context = this;
        if (!inThrottle) {
            func.apply(context, args);
            inThrottle = true;
            setTimeout(() => {
                inThrottle = false;
            }, limit);
        }
    };
}

// 使用节流处理滚动事件
window.addEventListener('scroll', throttle(() => {
    console.log('Scroll event');
}, 100));

这个示例中,throttle 函数确保 scroll 事件处理函数在100毫秒内最多只执行一次。

防抖(Debouncing)

在一定延迟时间内,连续触发的事件合并只执行 最后 一次。如果在指定的时间间隔内事件再次触发,则重新计时。

工作原理

  • 延迟时间:设置一个延迟时间(例如300毫秒)。
  • 事件触发:新的事件触发时,重新计时。
  • 函数执行:如果在延迟时间内没有再次触发事件,则执行函数。

image.png

示例:防抖

function debounce(func, delay) {
    let inDebounce;
    return function() {
        const context = this;
        const args = arguments;
        clearTimeout(inDebounce);
        inDebounce = setTimeout(() => {
            func.apply(context, args);
        }, delay);
    };
}

// 使用防抖处理输入事件
const inputField = document.querySelector('input');
inputField.addEventListener('input', debounce((event) => {
    console.log('Input event:', event.target.value);
}, 300));

在这个示例中, 函数确保 input 事件处理函数在用户停止输入300毫秒后才执行。

节流 VS 防抖

区别防抖(Debounce)节流(throttle)
描述一定延迟时间内,连续事件只执行最后一次一段固定时间内只执行一次
原理只保留一个延时setTimeout()的执行器,后续新的替代旧的判断时间间隔,在固定间隔时间内,只执行一次。
执行次数只执行最后一次执行首次、最后一次
合适场景连续操作只需要一次的,如变更内容提交到后端连续操作定期执行的场景:连续的UI交互,如拖拽、滚动

应用场景

节流(Throttling)

  • 滚动事件:当用户滚动页面时,频繁触发事件会导致性能问题。节流可以确保在滚动过程中,每隔固定时间只处理一次事件,从而减少性能开销。
  • 窗口调整大小:在调整窗口大小时,频繁触发 resize 事件。节流可以确保在调整窗口大小的过程中,每隔固定时间只处理一次事件。
  • 鼠标移动事件:在处理鼠标移动事件时,频繁触发事件会导致性能问题。节流可以确保在鼠标移动过程中,每隔固定时间只处理一次事件。

防抖(Debouncing)

  • 输入事件:在输入框中输入内容时,频繁触发 input 事件。防抖可以确保在用户停止输入一段时间后才处理事件,从而减少性能开销,适用于搜索建议、自动保存等功能。
  • 窗口调整大小:在调整窗口大小时,频繁触发 resize 事件。防抖可以确保在用户停止调整窗口大小一段时间后才处理事件,适用于需要在调整完成后进行布局调整的场景。
  • 按钮点击事件:在处理按钮点击事件时,防止用户快速多次点击。防抖可以确保在用户停止点击一段时间后才处理事件,适用于防止表单多次提交等场景。

常见的一些库

Lodash

Lodash 提供的 _.debounce_.throttle 函数可以让我们更方便地实现防抖和节流功能。

节流(Throttling)

import { throttle } from 'lodash';
function handleScroll() {
    console.log("Handling scroll event");
    // 实际滚动处理逻辑
}
const throttledHandleScroll = throttle(handleScroll, 200);
window.addEventListener('scroll', throttledHandleScroll);

防抖(Debouncing)

import { debounce } from 'lodash';
function logValue(value) {
    console.log(`Current value: ${value}`);
}
const debouncedLog = debounce(logValue, 300);
document.getElementById('inputBox').addEventListener('input', function(event) {
    const inputValue = event.target.value;
    debouncedLog(inputValue); // 使用防抖处理后的函数
});

文章参考