防抖和节流

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)​​(调整结束后再计算布局)
相关推荐
万少1 天前
HarmonyOS 开发必会 5 种 Builder 详解
前端·harmonyos
橙序员小站1 天前
Agent Skill 是什么?一文讲透 Agent Skill 的设计与实现
前端·后端
炫饭第一名1 天前
速通Canvas指北🦮——基础入门篇
前端·javascript·程序员
王晓枫1 天前
flutter接入三方库运行报错:Error running pod install
前端·flutter
符方昊1 天前
React 19 对比 React 16 新特性解析
前端·react.js
ssshooter1 天前
又被 Safari 差异坑了:textContent 拿到的值居然没换行?
前端
曲折1 天前
Cesium-气象要素PNG色斑图叠加
前端·cesium
Forever7_1 天前
Electron 淘汰!新的桌面端框架 更强大、更轻量化
前端·vue.js
Angelial1 天前
Vue3 嵌套路由 KeepAlive:动态缓存与反向配置方案
前端·vue.js
jiayu1 天前
Angular学习笔记24:Angular 响应式表单 FormArray 与 FormGroup 相互嵌套
前端