防抖和节流

1. 节流(稀释操作)

规定在⼀个周期内,事件最多触发⼀次。如果事件在周期内再次触发,则忽略。

作用

在事件持续触发时,保证固定时间间隔内只执行一次。

常见场景:

滚动事件(scroll)、按钮点击防重复提交等。

常⻅实现思路:

当前时间 - 上次触发的时间 >= delay

使⽤⼀个时间戳记录上次触发的时间,判断当前触发距离上次触发的时间间隔是否⼤于等于指定的周期。 节流(Throttle)和防抖(Debounce)是控制函数执行频率的两种常用技术,它们有各自清晰的适用场景。

js 复制代码
// 节流函数
function throttle(fn, delay = 300) {
  let last = 0
  return function (...args) {
    const context = this
    const now = Date.now()
    if (now - last >= delay) {
      fn.apply(context, args)
      last = now
    }
  }
}

2.防抖(多次操作合并成最后一次)

在事件频繁触发时,只在最后一次触发后等待一段时间再执行。

常⻅实现思路

使⽤ setTimeout 设置⼀个定时器,如果事件在定时器到期前再次触发,则清除之前的定时器,并重新设置⼀个新的定时器。

常见场景

搜索框输入联想​ ​(停止输入后再请求),表单验证​​(输入完成后再校验)

js 复制代码
// 防抖函数
function debounce(fn, delay = 300) {
  let timer = null
  return function (...args) {
    const context = this
    if (timer) clearTimeout(timer)
    timer = setTimeout(() => {
      fn.apply(context, args)
      timer = null
    }, delay)
  }
}

立即执行的防抖

js 复制代码
function advancedDebounce(fn, delay, immediate = false) {
    let timer = null;
    
    const debounced = function(...args) {
        const context = this;
        
        if (timer) clearTimeout(timer);
        
        if (immediate) {
            const callNow = !timer;
            timer = setTimeout(() => {
                timer = null;
            }, delay);
            
            if (callNow) fn.apply(context, args);
        } else {
            timer = setTimeout(() => {
                fn.apply(context, args);
                timer = null
            }, delay);
        }
    };
    
    // 添加取消方法
    debounced.cancel = function() {
        if (timer) {
            clearTimeout(timer);
            timer = null;
        }
    };
    
    return debounced;
}

📊 核心区别一览

对比维度 ​节流 (Throttle)​ ​防抖 (Debounce)​
​核心思想​ 固定时间间隔内只执行一次,​​稀释执行频率​​。 连续触发时,只在最后一次触发后等待一段时间才执行,​​合并多次操作​​。
​生活类比​ 像​​机关枪扫射​​,无论扣动扳机多快,子弹都按固定频率发射。 像​​电梯关门​​,有人进入后等待几秒关门,若期间有人进入则重新等待。
​执行时机​ ​固定间隔执行​​,保证在单位时间内至少执行一次。 ​延迟执行​​,只在连续触发停止后执行一次。
​关键区别​ 关注​​过程的均匀性​​,不会丢失中间事件。 关注​​结果的唯一性​​,可能丢弃中间过程,只保留最终状态。
​典型场景​ - ​​滚动事件​ ​(如无限加载) - ​​鼠标移动​ ​(如元素拖拽、Canvas绘图) - ​​窗口调整(resize)​ ​(需持续反馈布局时) - ​​按钮高频点击​​(如防止重复提交) - ​​搜索框输入联想​ ​(停止输入后再请求) - ​​表单验证​ ​(输入完成后再校验) - ​​窗口调整(resize)​​(调整结束后再计算布局)
相关推荐
鹏北海6 小时前
多标签页登录状态同步:一个简单而有效的解决方案
前端·面试·架构
_AaronWong6 小时前
基于 Vue 3 的屏幕音频捕获实现:从原理到实践
前端·vue.js·音视频开发
孟祥_成都6 小时前
深入 Nestjs 底层概念(1):依赖注入和面向切面编程 AOP
前端·node.js·nestjs
let_code6 小时前
CopilotKit-丝滑连接agent和应用-理论篇
前端·agent·ai编程
Apifox6 小时前
Apifox 11 月更新|AI 生成测试用例能力持续升级、JSON Body 自动补全、支持为响应组件添加描述和 Header
前端·后端·测试
木易士心6 小时前
深入剖析:按下 F5 后,浏览器前端究竟发生了什么?
前端·javascript
在掘金801106 小时前
vue3中使用medium-zoom
前端·vue.js
xump7 小时前
如何在DevTools选中调试一个实时交互才能显示的元素样式
前端·javascript·css
折翅嘀皇虫7 小时前
fastdds.type_propagation 详解
java·服务器·前端
Front_Yue7 小时前
深入探究跨域请求及其解决方案
前端·javascript