1.防抖(debounce)
防抖策略 (debounce)当事件被触发时,延迟N秒才执行,如果在这N秒内再次被触发将重新计时。

防抖的应用场景:用户在很短的时间内连续点击表单按钮,频繁的执行回调导致数据的不一致性。
==用简单的话来说,防抖就是只执行最后一次。==
防抖实现的基本思路: 在第一次触发事件时,不立即执行函数,而是给出一个期限值比如200ms,然后:
效果:如果短时间内大量触发同一事件,只会执行一次函数。
实例:
data.json
{
"code": 200,
"msg": "success"
}
demo.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>防抖与节流</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
</head>
<body>
<div>
<button id="bt1">未添加防抖功能</button>
<br>
<br>
<button id="bt2">已添加防抖功能</button>
<br>
</div>
<script>
let timer = null
$("#bt1").click(() => {
//console.log("btn1 is clicked...")
$.ajax({
url: 'data.json',
type: 'get',
success: resp => console.log(resp)
})
});
$("#bt2").click(() => {
//console.log("btn2 is clicked...")
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
$.ajax({
url: 'data.json',
type: 'get',
success: resp => console.log(resp)
})
}, 2000)
});
</script>
</body>
</html>
执行效果: 快速点击按钮1,会频繁执行回调。如下图:
快速点击按钮2,在两秒内仅仅执行一次。如下图:

2.节流(throttle)
节流可以减少一段时间内事件的触发频率。
==简单来说节流就是控制事件触发的次数。==
实现节流其实很简单:我们可以设计一种类似控制阀门一样定期开放的函数,也就是让函数执行一次后,在某个时间段内暂时失效,过了这段时间后再重新激活(类似于技能冷却时间)。
如果短时间内大量触发同一事件,那么在函数执行一次之后,该函数在指定的时间期限内不再工作,直至过了这段时间才重新生效。
首先下面有一段这样的代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>防抖与节流</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
</head>
<body>
<div>
<br>
<br>
<br>
<br>
<br>
<br>
</div>
<script>
window.addEventListener('scroll',function(){
console.log('scrolling...');
});
</script>
</body>
</html>
执行效果: 每次滚动都会触发这个事件,但是仅仅几秒钟就已经触发了一两百次,那如果是和后台交互数据的话,这样的频率和数据量会占很多带宽,会很耗性能。那么我们就会想到,能不能让它的执行次数减少,这个就是节流的初衷。

有了最初始的问题了,那么现在就来解决问题! 解决这个问题,会用到一个 开关思想 那么代码如下:
let flag = true;
window.addEventListener('scroll', function () {
if(flag){
setTimeout(()=>{
console.log('scrolling...');
flag = true;
},1000);
}
flag = false;
//console.log('scrolling...');
});
进一步优化代码,将全局变量去掉,进行一个优化,进行封装,代码如下:
window.onscroll = throttle(function () {
console.log('scrolling');
}, 1000)
function throttle(fn, delay) {
var flag = true;
return function () {
if (flag) {
setTimeout(() => {
fn.call(this)
flag = true;
}, delay);
}
flag = false;
}
}
每次经过1000ms打印一次,(时间根据所需更改)这样就解决了事件的触发频率过快的情况。

3.loadash.js实现防抖和节流
Lodash是一个一致性、模块化、高性能的 JavaScript实用工具库。里面提供了debounce/throttle函数。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--引入鲁大师库-->
<script src="https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>
</head>
<body>
<div>
<button id="btn">点我</button>
</div>
<script>
function test(){
console.log('点你妹啊....')
}
document.getElementById("btn").addEventListener("click",_.debounce(test,1000));
</script>
</body>
</html>