节流与防抖的概念
函数节流与函数防抖的目的都是为了减少用户对服务器不必要的请求次数,以此提高服务器性能的函数。节流是在一段时间内,只向服务器请求一次。防抖则是在频繁触发相同请求时,若任务之间间隔小于指定时间,那么只会执行最后一次请求。
防抖
思路:每次触发事件时都取消之前的延时调用方法
先看下面一段代码
代码语言:javascript复制<input type="text" id="text">
<script>
//模拟ajax请求
const ajax = (content) => {
console.log(content)
}
document.querySelector('#text').addEventListener('input',(e)=>{
ajax(e.target.value)
})
</script>
上面的代码是未做防抖的思路,监听input元素的input
事件,随后得到值以后,模拟触发像后端请求接口,这样做能得到我们想要的数据。但是这样做非常消耗服务器的性能,例如我们在搜索商品时,获取用户输入的值以后,展示给用户一些提示商品的列表。加入用户想搜索nike
这个关键词,下面是模拟请求的结果,这里有看到请求依次请求了n,ni,nik,nike
,我们这里其实只需要请求一次nike
就可以了。这还只是算的1个用户,通过防抖我们将4次请求优化至1此请求。如果同时访问的是1万人,那么4万次请求和1万次请求差距就相当大了。
根据上诉的问题,我们优化一下代码。
1. 添加debounce函数
我们先添加一个debounce
函数,调试一下看看函数能否正常调用,发现是可以正常调用的。
<input type="text" id="text">
<script>
//模拟ajax请求
const ajax = (content) => {
console.log(content)
}
const debounce = (fn) => {
return () => {
fn()
}
}
document.querySelector('#text').addEventListener('input',(e)=>{
debounce(ajax)(e.target.value)
})
</script>
2. 回顾概念
防抖的概念则是在任务之间间隔小于指定时间时,只会触发一次请求,那么这里的debounce函数还需要一个delay
时间参数,涉及到时间,则需要一个添加一个定时器,接下来再次修改函数。
<input type="text" id="text">
<script>
//模拟ajax请求
const ajax = (content) => {
console.log(content)
}
const debounce = (fn,delay) => {
return (args) => {
clearTimeout(fn.id)
fn.id = setTimeout(function () {
fn(args)
}, delay)
}
}
document.querySelector('#text').addEventListener('input',(e)=>{
debounce(ajax,500)(e.target.value)
})
</script>
我们再把调用debounce函数写的更优雅一些
代码语言:javascript复制<input type="text" id="text">
<script>
//模拟ajax请求
const ajax = (content) => {
console.log(content)
}
const debounce = (fn,delay) => {
return (args) => {
clearTimeout(fn.id)
fn.id = setTimeout(() => {
fn(args)
}, delay)
}
}
const oDebounce = debounce(ajax,500)
document.querySelector('#text').addEventListener('input',(e)=>{
oDebounce(e.target.value)
})
</script>
好了一个防抖函数就完成了。
节流
思路:每次触发事件时都判断当前是否有等待执行的延时函数
和防抖一样,节流也是为了降低服务器的性能。不过节流时在一段时间内只执行一次函数。简单做一点修改,下面则是一个节流函数。
代码语言:javascript复制<script>
//模拟ajax请求
const ajax = (content) => {
console.log(content)
}
const throttle = (fn,delay) => {
let timer = true
return (args) => {
if(!timer) return
timer = false
clearTimeout(fn.id)
fn.id = setTimeout(() => {
fn(args)
timer = true
}, delay)
}
}
const oThrottle = throttle(ajax,500)
document.querySelector('#text').addEventListener('input',(e)=>{
oThrottle(e.target.value)
})
</script>