🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6
🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1
🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》
🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入门到实战全面掌握 uni-app》
摘要
防抖和节流是在 JavaScript
中常用的两种技术,用于限制某个函数在短时间内被频繁调用。防抖的原理是在事件被触发后,延迟一定时间执行函数,如果在延迟时间内触发了该事件,则重新计时,直到延迟时间内没有再次触发事件,才执行函数。节流的原理是在规定的时间内,只让函数执行一次,无论事件触发的频率如何。
一、引言
在前端开发中,我们经常会遇到一些需要限制某个函数在短时间内被频繁调用的情况。例如,搜索框的联想功能、页面滚动加载更多内容等。为了解决这些问题,我们可以使用防抖和节流技术。
二、正文
(一)防抖 (debounce)
防抖的原理是在事件被触发后,延迟一定时间执行函数,如果在延迟时间内触发了该事件,则重新计时,直到延迟时间内没有再次触发事件,才执行函数。
一个比较好的解释是:当一次事件发生后,事件处理器要等一定阈值的时间,如果这段时间过去后再也没有事件发生,就处理最后一次发生的事件。
防抖函数的实现可以使用 JavaScript 的定时器。以下是一个简单的防抖函数示例:
「防抖重在清零 clearTimeout(timer)」
function debounce(fn, delay) {
let timer;
return function() {
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this, arguments);
}, delay);
};
}
在上述示例中,debounce
函数接受两个参数:fn
是要防抖的函数,delay
是延迟时间(毫秒)。返回的函数会在每次事件触发时清除定时器,并重新设置一个定时器,当延迟时间内没有再次触发事件时,执行 fn
函数。
(二)节流 (throttle)
节流的原理是在规定的时间内,只让函数执行一次,无论事件触发的频率如何。它和防抖最大的区别就是,节流函数不管事件触发有多频繁,都会保证在规定时间内一定会执行一次真正的事件处理函数。
比如在页面的无限加载场景下,我们需要用户在滚动页面时,每隔一段时间发一次 Ajax 请求,而不是在用户停下滚动页面操作时才去请求数据。这样的场景,就适合用节流阀技术来实现。
节流函数的实现可以使用时间戳或定时器。以下是一个使用定时器实现的简单节流函数示例:
「节流重在开关锁 timer=null」
function throttle(fn, delay) {
let flag = true;
return function() {
if (flag) {
flag = false;
setTimeout(() => {
fn.apply(this, arguments);
flag = true;
}, delay);
}
};
}
在上述示例中,throttle
函数接受两个参数:fn
是要节流的函数,delay
是延迟时间(毫秒)。返回的函数会在每次事件触发时将 flag
设置为 false
,然后设置一个定时器,当延迟时间内没有再次触发事件时,执行 fn
函数,并将 flag
设置为 true
。
(三)防抖和节流的应用场景
防抖和节流都可以应用于以下场景:
- 搜索框联想:用户在输入时,防抖可以限制频繁的请求,只有在用户停止输入一段时间后才发送请求。
- 页面滚动加载:在滚动页面时,节流可以限制加载更多内容的频率,避免频繁请求数据。
- 按钮提交:防抖可以防止用户在短时间内多次点击提交按钮,导致重复提交。
- 实时数据更新:在实时数据更新的场景中,防抖可以限制频繁的请求,只在数据有变化时发送请求。
- 焦点失焦:节流可以限制焦点失焦事件的触发频率,避免频繁执行相关操作。
三、总结
防抖:防止抖动,单位时间内事件触发会被重置,避免事件被误伤触发多次。代码实现重在清零 clearTimeout
节流:控制流量,单位时间内事件只能触发一次,如果服务器端的限流即 Rate Limit。代码实现重在开锁关锁
timer=timeout; timer=null
防抖和节流都是用于限制某个函数在短时间内被频繁调用的技术。防抖的原理是在事件被触发后,延迟一定时间执行函数,如果在延迟时间内触发了该事件,则重新计时,直到延迟时间内没有再次触发事件,才执行函数。节流的原理是在规定的时间内,只让函数执行一次,无论事件触发的频率如何。这两种技术在前端开发中有广泛的应用,可以提高页面性能和用户体验。