JavaScript 防抖、节流

1|0debounce 定义

防抖(debounce):不管事件触发频率多高,一定在事件触发n秒后才执行,如果你在一个事件触发的 n 秒内又触发了这个事件,就以新的事件的时间为准,n 秒后才执行,总之,触发完事件 n 秒内不再触发事件,n秒后再执行。(类比乘坐电梯)

1|1应用场景

1|0窗口大小变化,调整样式
window.addEventListener('resize', debounce(handleResize, 200));
1|0搜索框,输入后1000毫秒搜索
debounce(fetchSelectData, 300);
1|0表单验证,输入1000毫秒后验证
debounce(validator, 1000);

1|2图示

img

1|3实现

注意考虑两个问题:

  • debounce函数中返回一个闭包,这里用的普通function,里面的setTimeout则用的箭头函数,这样做的意义是让this的指向准确,this的真实指向并非debounce的调用者,而是返回闭包的调用者。
  • 对传入闭包的参数进行透传。
function debounce(event, time) { let timer = null; return function (...args) { clearTimeout(timer); timer = setTimeout(() => { event.apply(this, args); }, time); }; }

有时候我们需要让函数立即执行一次,再等后面事件触发后等待n秒执行,我们给debounce函数一个flag用于标示是否立即执行。

当定时器变量timer为空时,说明是第一次执行,我们立即执行它。

function debounce(event, time, flag) { let timer = null; return function (...args) { clearTimeout(timer); if (flag && !timer) { event.apply(this, args); } timer = setTimeout(() => { event.apply(this, args); }, time); }; }

2|0throttle 定义

节流(throttle):不管事件触发频率多高,只在单位时间内执行一次。(类比乘坐地铁)

2|1应用场景

降低事件触发频率。比如懒加载时要监听计算滚动条的位置,但不必每次滑动都触发,可以降低计算的频率,而不必去浪费资源。

2|2图示

img

2|3实现

有两种方式可以实现节流,使用时间戳和定时器。

1|0时间戳实现

第一次事件肯定触发,最后一次不会触发

function throttle(event, time) { let pre = 0; return function (...args) { if (Date.now() - pre > time) { pre = Date.now(); event.apply(this, args); } }
1|0定时器实现

第一次事件不会触发,最后一次一定触发

function throttle(event, time) { let timer = null; return function (...args) { if (!timer) { timer = setTimeout(() => { timer = null; event.apply(this, args); }, time); } } }
1|0结合版

定时器和时间戳的结合版,也相当于节流和防抖的结合版,第一次和最后一次都会触发

function throttle(event, time) { let pre = 0; let timer = null; return function (...args) { if (Date.now() - pre > time) { clearTimeout(timer); timer = null; pre = Date.now(); event.apply(this, args); } else if (!timer) { timer = setTimeout(() => { event.apply(this, args); }, time); } } }

debounce.mdthrottle.md


__EOF__

本文作者shmillly959
本文链接https://www.cnblogs.com/shmillly959/p/13724133.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   shmillly959  阅读(73)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示