什么是防抖
防抖(Debounce)是一种编程技巧,主要用于处理连续触发的事件,确保在一定时间内只执行一次该事件的处理函数。它的核心目的是为了限制某些函数的执行频率,以提高性能和效率,避免因短时间内频繁调用而造成的资源浪费,比如网络请求过多、DOM操作频繁等。
具体实现上,防抖函数通常会创建一个计时器,在事件被触发时,若计时器已经存在(即前一次触发还在延迟执行中),则会清除当前计时器并重新开始计时;如果在设定的延迟时间结束后没有新的事件触发,则执行目标函数。这样一来,如果事件触发非常频繁(如快速连续按键、窗口大小调整等),则只有在最后一次触发后的一段时间没有新的触发,对应的处理函数才会被执行。
例如,在搜索框的应用场景中,如果没有使用防抖,用户每输入一个字符就可能发送一次查询请求到服务器,这不仅消耗网络资源,也会给服务器带来不必要的负担。而应用了防抖技术后,只有当用户停止输入一段时间后,才会发送查询请求,大大减少了请求次数,提高了效率。
不防抖实现
- 首先创建一个文件夹,初始化
- 引入json-server接口,用来驱动后端
- 创建一个json文件, 在里面放入json内容
{
"users": [
{
"id": 1,
"name": "奶茶"
},
{
"id": 2,
"name": "wow奶茶"
},
{
"id": 3,
"name": "wow红茶"
}
]
}
- 在package.json文件夹下,改成如下图
- 在命令行输入 npm run dev 就可以驱动json文件,获取本地的运行地址
进入网页就可以看到自己创建的json内容
- 直接输入/1就可以获取id为1的内容
- 新建html文件来实现搜索框的效果
<div>
没有防抖的input
<input
type="text"
id="unDebounce"
placeholder="请输入你要搜索的用户名"
>
</div>
<script>
// 不加防抖的
const inputa = document.getElementById('unDebounce');
function handleNameSearch(e){
const value = e.target.value;
fetch('http://localhost:3000/users')
.then(res => res.json())
.then(data =>{
const users = data;
const filterUsers= users.filter(user =>{
return user.name.includes(value)
})
console.log(filterUsers)
})
}
- e.target.value每打按一次键盘就会执行一次代码,明显会造成数据的大量冗余,这对于大型搜索引擎来说,就是个巨大的灾难。
问题
- 用户在
unDebounce输入框中每输入一个字符,都会立即触发handleNameSearch函数。 - 函数内部会获取当前输入框的值,并打印出来。实际应用中,这里会发起一个异步请求到服务器,查找匹配的用户名。
- 由于没有防抖机制,如果用户快速连续输入,每次输入都会触发请求,可能会导致大量不必要的网络请求,增加服务器负担。
防抖实现
直接使用上面的代码
<div>
没有防抖的input
<input
type="text"
id="unDebounce"
placeholder="请输入你要搜索的用户名"
>
</div>
<script>
// 不加防抖的
const inputb = document.getElementById('debounce')
function handleNameSearch(e){
const value = e.target.value;
fetch('http://localhost:3000/users')
.then(res => res.json())
.then(data =>{
const users = data;
const filterUsers= users.filter(user =>{
return user.name.includes(value)
})
console.log(filterUsers)
})
}
const debounceNameSearch = debounce(handleNameSearch,1000)
function debounce(func,delay){
// 返回值必须得是函数 keyup 事件处理函数
// let id;
return function(args){
clearTimeout(func.id)
// 函数是对象,id 挂在func上 func 是闭包中的自由变量
func.id = setTimeout(()=>{
func(args)
},delay)
}
}
在最后添加了一个闭包,会在你输入后的1秒后,开始筛选内容,实现浏览器中的搜索推荐效果
结语
对于防抖的代码来说,推荐各位都去亲自对比和实现,时间的差异在自己实现后才能感觉到,实践是检验真理的唯一标准。