从小实例引入问题
直接上图~
当我们在页面文本框中输入文字点击提交时,页面就会将数据提交给后端;当我们点击10次的时候就会发10次请求,但是其实一次请求就行了,剩下的9次请求毫无意义,这样就会加重浏览器负载,影响用户体验。在前段开发的过程中我们经常会绑定一些持续触发的事件,但有些时候我们并不希望在事件持续触发的过程中那么频繁地去执行函数,这就需要我们去手写实现防抖与节流。
防抖(debounce)
什么是防抖?
在触发一次函数后的规定时间内没有再次触发,才执行。如果多次触发函数,只有最后一次执行。用一句话概括为:
将多次执行变为最后一次执行。
原理
原理是维护一个计时器
setTimeout,在规定的时间time后执行函数,但在这个时间内再次触发此函数的话,通过clearTimeout清除上一个计时器然后重新设置,这样就只有最后一步操作才会执行。
实现
function debounce(func) {
var timeout;
//返回出函数形成闭包
return function () {
//在规定时间内再次执行此函数时清除上一个计时器
clearTimeout(timeout)
//创建一个计时器在规定时间内执行函数
timeout = setTimeout(() => {
//执行传入进来的函数
func()
}, 1000)
}
}
代码优化
function debounce(func, time) {
//定义变量接受计时器,函数执行结果
var timeout, result;
//返回出函数形成闭包
return function () {
let that = this
//解构传入进来的参数
let args = [...arguments]
//在规定时间内再次执行此函数时清除上一个计时器
clearTimeout(timeout)
//创建一个计时器在规定时间内执行函数
timeout = setTimeout(() => {
//执行传入进来的函数,改变this指向返回出去的函数,接受参数
result = func.apply(that, args)
}, time)
//返回函数执行结果
return result
}
}
节流(throttle)
什么是节流?
如果一个事件被频繁触发多次,节流可以按照固定的频率去执行相应的事件处理方法。用一句话概括为:
将多次连续的执行变成每隔一段时间执行。
原理
利用
+new Date()获取当前时间,然后定义一个变量记录上一次获取到的时间,当事件频繁触发时只要两者的时间差大于用户规定的时间time,函数就执行,否则不执行。
实现及优化
function throttle(func, time) {
//定义原始时间为0 变量result接受函数执行结果
let preTime = 0
let result
//返回函数形成闭包
return function () {
//解构传入进来的参数
let args = [...arguments]
//获取当前触发事件时的时间
let now = +new Date()
//判断时间间隔是否大于用户的要求,是的话执行
if (now - preTime > time) {
//执行传入进来的函数,改变this指向返回出去的函数,接受参数
result = func.apply(this, args)
//记录上一次触发函数的时间
preTime = now
}
//返回函数执行结果
return result
}
}
防抖与节流的区别
防抖和节流这俩哥们无论声音相貌长得都非常像,就像双胞胎一样,有时候难免混为一谈。但是双胞胎也会有不一样的地方,这里我们就来聊聊防抖与节流不太一样的地方。
防抖我们来举个实例: 在百度搜索框中输入内容,然后弹出联想词,弹出联想词一般是你输入完成后再过一会儿执行的,也就是最后才会执行。
而节流就不一样了,它是每隔一段时间触发;就比如当你上线QQ网页版的时候,你的好友是一部分一部分加载出来的。就是某事件高频触发,但在n秒内只会执行一次。
总结
防抖与节流在面试中是常考的一个考点,当然以后我们在做项目的过程中也会用到防抖与节流等工具函数,可以大大提高我们的开发效率。最后感谢各位的观看。