本文已参与「新人创作礼」活动,一起开启掘金创作之路。
前言
防抖和节流,这是前端防止用户频繁调用同一个接口的方法,比如短时间重复点击上传同一个文件,短时间重复点击提交同一个评论,异步的操作还没给你带来反馈,于是你重复上传了多个文件,重复提交了多个评论。
本文以常见的使用场景与解决方案,一篇教会你如何使用防抖节流。
场景
为了例子更加简单,我们就用延迟来模拟一个后端接口返回的过程。
<body>
<button onclick="comment()">发表评论</button>
<script>
const commentApi = () => {
// 我们使用延迟模拟异步请求
setTimeout(() => {
const div = document.createElement('div')
div.innerText = '本人到此一游'
document.body.appendChild(div)
}, 1000)
}
const comment = () => {
// 请求发布评论Api
commentApi()
}
</script>
</body>
复制代码
以上是一个发表评论的例子,由于接口一秒后才会响应评论反馈到界面上。
用户本意只是发布一条评论,但是由于接口需要响应时间,他以为自己的第一次点击没有生效于是就多点击了两次,结果显而易见,就是非用户本意的发布了三条一样的评论。
我们希望的是用户不要在请求还在进行的时候,频繁的重复发送请求。这时候就需要防抖节流了。
防抖
核心
- 设置延迟,短时间高频率触发只有最后一次触发成功
解释
防抖指的是设置延时器,比方说我点击之后设置一个1s的延迟,1s后开始上传。
如果在1s之中再次点击该事件,那么这个延迟被清除,重置1s的延迟,也就是还没开始上传你得重新等待1s。
也就是无论你如何一直乱点,也只有你停止点击后的最后一次点击会成功。
修复场景例子
快速点击几次,还是只会发送一条评论。
但是缺点就是用户得到响应的时间更久了,得要算上延迟加上接口的响应。
<body>
<button onclick="comment()">发表评论</button>
<script>
const commentApi = () => {
// 我们使用延迟模拟异步请求
setTimeout(() => {
const div = document.createElement('div')
div.innerText = '本人到此一游'
document.body.appendChild(div)
}, 1000)
}
let later
const comment = () => {
// 如果已经设置过延迟请求,则重置延迟
if (later) {
clearTimeout(later)
}
later = setTimeout(() => {
commentApi()
}, 1000)
}
</script>
复制代码
所以防抖一般也不完全适合此类型的场景,它更适合需要一定操作结束之后再执行的场景,比如请你输入一段话,输入结束之后再进行请求,当然不希望你在输入的过程中就开始请求了,于是设置防抖,直到发觉你停止输入了才开始请求。
节流
核心
- 设置状态锁,短时间高频率触发只有第一次会触发成功
解释
节流是设置状态锁,比如设置一个key作为锁,锁一开始的状态是关闭的,我们将key设置为false。
当你点击的时候,会对key进行判断,如果发现key为false,未上锁,那么开始请求,并且与此同时给key上锁,将flag设置为true。
然后这时候你继续点击请求的时候,同样要判断key,发现上锁了,你怎么点击也没用。
然后什么时候再将锁关闭呢?在你接口返回给前端,提示你已经上传完毕了之后,再将key关闭置为false,就可以再次提交请求了。
修复场景例子
快速点击几次,还是只会发送一条评论。只有一条请求发布成功之后,才能够发布第二条请求,对于该场景十分合适。
<body>
<button onclick="comment()">发表评论</button>
<script>
let key = false
const commentApi = () => {
setTimeout(() => {
const div = document.createElement('div')
div.innerText = '本人到此一游'
document.body.appendChild(div)
// 请求结束,解锁
key=false
}, 1000)
}
const comment = () => {
// 未上锁开始执行
if (!key) {
// 请求开始,上锁
key = true
commentApi()
}
}
</script>
</body>
复制代码
尾言
如果觉得文章对你有帮助的话,欢迎点赞收藏哦,有什么错误或者意见建议也可以留言,感谢~