防抖和节流

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)​​(调整结束后再计算布局)
相关推荐
发现一只大呆瓜33 分钟前
虚拟列表:支持“向上加载”的历史消息(Vue 3 & React 双版本)
前端·javascript·面试
css趣多多1 小时前
ctx 上下文对象控制新增 / 编辑表单显示隐藏的逻辑
前端
_codemonster1 小时前
Vue的三种使用方式对比
前端·javascript·vue.js
寻找奶酪的mouse1 小时前
30岁技术人对职业和生活的思考
前端·后端·年终总结
梦想很大很大1 小时前
使用 Go + Gin + Fx 构建工程化后端服务模板(gin-app 实践)
前端·后端·go
We་ct1 小时前
LeetCode 56. 合并区间:区间重叠问题的核心解法与代码解析
前端·算法·leetcode·typescript
张3蜂1 小时前
深入理解 Python 的 frozenset:为什么要有“不可变集合”?
前端·python·spring
无小道1 小时前
Qt——事件简单介绍
开发语言·前端·qt
广州华水科技1 小时前
GNSS与单北斗变形监测技术的应用现状分析与未来发展方向
前端
code_YuJun2 小时前
corepack 作用
前端