Js实现防抖节流

前言

防抖节流是经常在开发中用到的一个东西,都是用来控制某个函数在一定时间内触发次数,两者都是为了减少触发频率,以便提高性能或者说避免资源浪费。

防抖: n 秒后在执行该事件,若在 n 秒内被重复触发,则重新计时

节流: n 秒内只运行一次,若在 n 秒内重复触发,只有一次生效

手写防抖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<body>
<button id="FangDou">防抖</button>
</body>
</html>

<script>
var btn = document.querySelector('#FangDou')
// 手写防抖
// 防抖是函数在n秒内重复触发,则重新计时
// func 要进行防抖的方法,delay是要防抖的时间
function debounce(func, delay){
// 声明变量来保存计时,让其作为局部变量保存在内存中,且不被随意访问,借助闭包来实现
let timer = null;
// 返回一个闭包,通过return的函数可以来间接访问timer,
return function(){
// 保存闭包被调用时的this
// let that = this
// 如果时间期限还没到又触发了,则清除上一个定时器,重新计算时间
if(timer){
// 清除定时器,debounce执行时要先把之前的setTimeout先清除再重新计时。
clearTimeout(timer)
}
// 箭头函数的this永远指向外层作用域的this
timer = setTimeout(() => {
// 使用apply来改变this指向,apply函数会执行fn函数,并改变this指向
func.apply(this, arguments);
// 执行完毕之后,再把timer设为null
timer = null
}, delay)
}
}

function play(){
console.log(11111)
}

btn.onclick = debounce(this.play , 500)

</script>

手写节流

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 手写节流
// 节流是函数在n秒内重复触发,只触发一次
// func 要进行节流的方法,delay是要节流的时间
function throttle(func , delay){
let timer = null
return function(){
// 每次触发事件时,如果当前有等待执行的函数,则直接return
if(timer){
return ;
}
timer = setTimeout(() => {
func.apply(this , arguments)
timer = null
}, delay);
}
}