防抖和节流

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)​​(调整结束后再计算布局)
相关推荐
JustHappy几秒前
「chrome extensions🛠️」我写了一个超级简单的浏览器插件Vue开发模板
前端·javascript·github
Loo国昌2 分钟前
Vue 3 前端工程化:架构、核心原理与生产实践
前端·vue.js·架构
sg_knight5 分钟前
拥抱未来:ECMAScript Modules (ESM) 深度解析
开发语言·前端·javascript·vue·ecmascript·web·esm
LYFlied5 分钟前
【每日算法】LeetCode 17. 电话号码的字母组合
前端·算法·leetcode·面试·职场和发展
开发者小天6 分钟前
react中useEffect的用法,以及订阅模式的原理
前端·react.js·前端框架
前端白袍26 分钟前
Vue:如何实现一个具有复制功能的文字按钮?
前端·javascript·vue.js
new code Boy1 小时前
escape谨慎使用
前端·javascript·vue.js
叠叠乐1 小时前
robot_state_publisher 参数
java·前端·算法
Kiri霧1 小时前
Range循环和切片
前端·后端·学习·golang
小张快跑。2 小时前
【Java企业级开发】(十一)企业级Web应用程序Servlet框架的使用(上)
java·前端·servlet