JavaScript之节流
在JavaScript中,节流(throttle)和防抖(debounce)是两种优化技术,用于控制函数执行的频率,以避免在短时间内多次调用某个函数,从而提升性能。它们常用于处理用户的高频事件,例如滚动、窗口调整大小、按键输入等。
节流
它的意思就是在一个单位时间内,之允许函数执行一次。试想一下页面中有一个输入框,你要获取输入框的值,你会获得这样的效果。
就是说你每输入一个字母他都会打印一次,那如果这是个网络请求呢?我想搜的是朝花夕拾这个书,按理讲只需要一个朝花夕拾,往服务器发个请求就好了,这下倒好拼音也发给服务器了,一下发这么多请求,性能上就不是很好了。这个时候就可以考虑节流了。下面手写一个节流函数并且讲一下执行过程。
<script>
// 获取input框
const input = document.querySelector('input')
// 定义方法,输出input的值
function keyVal() {
console.log(input.value)
}
// 定义节流函数
function throttle(fn, t) {
let timer
return function () {
if(!timer) {
timer = setTimeout(function () {
fn()
timer = null
}, t)
}
}
}
// 添加事件
input.addEventListener('keyup', throttle(keyVal, 1000))
</script>
重点在throttle
函数,这个函数接收两个参数,fn
就是要执行的函数,t
表示等待的时间。声明一个timer
变量,这个变量是用来存放定时器的,这是干嘛呢?节流的概念就是在一定时间内,这里我就设置为1秒,也就是说在1秒内只能执行一次fn
这个函数。那就要判断有没有定时器开启,如果有定时器开着,就不往下执行了,如果没有定时器,就接着执行下面的代码。有朋友就要说了我就不声明定时器变量能咋样?如下图所示。
如果不声明,节流就是笑话,输入6个数,函数执行了6次,只是每次执行之间间隔1秒。我们想要的是1秒之内就执行一次函数,达到节流的目的,所以要声明一个变量,来存放定时器,如果有一个定时器还没执行完,那就不要接着执行后面的代码了。估计朋友们还有一个疑问,为什么要retur
一个匿名函数。这时候我们想一想正常给元素添加事件是怎么写的。正常后面是一个匿名函数。
input.addEventListener('keyup', function (){
// 执行逻辑
})
这是其一,还有一个原因就是函数名后面加()
的意思是调用函数。
input1.addEventListener('keyup', throttle(keyVal, 1000))
如果说你不去return
一个匿名函数的话,这个里页面一加载就调用throttle
这个函数了,然后你在输入之后就没反应了。这里的原理就是闭包,什么是闭包后面详细说,这篇就说说节流。最后给大家看一下节流的效果。
同样6个数字就打印了1次,这代表1秒钟之内就执行了1次函数,当然这六个数字也是1秒钟之内输入完成的。后面关于防抖和闭包也会更新。