防抖和节流都是为解决短时间内频繁触发某个功能函数而导致的性能问题。比如,触发频率过高而导致响应速度跟不上,以致出现延迟,假死或卡顿的现象。
防抖
图解:一件事情,计划5s以后触发,结果中途意外触发了,那么就重新从0开始5秒的计时,这就导致本身计划的事情就延迟触发了,当...在延迟的5秒过程当中又再次意外触发了,就继续从0开始5秒的计时,而不会执行事件处理函数,那么什么时候触发5s后的事件呢,就是不再触发的时候。
函数防抖 代码解:
看下面防抖函数,每次触发时 有定时器 就 clearTimeout 清空定时器,如果频繁触发就一直清空定时器, 等停止触发的时候,只执行最后一次定时器事件才会发送请求, 这种函数虽然会多次执行 但是最终的有效代码 只执行一次的行为 称为 防抖。
// 防抖函数
function debounce(delay) {
let timer //声明一个存储定时器的变量
return function () {
if (timer) clearTimeout(timer)
timer = setTimeout(() => {
// 暂时理解不了(this,arguments)指向改变的问题
// getList.call(this, arguments)
getList(obj)
// 不输入延迟 则默认 1000 ms
}, delay || 1000)
}
}
防抖后的效果:看!!!等停止触发的时候,只执行最后一次事件,就是防抖的核心。
如果停止输入但是在指定间隔内又输入,会重新触发计时。
节流
介绍:js 节流阀
通过判断是否到达一定时间来触发回调函数。
顾名思义节流,也是节省能耗的一种,防止多次频繁触发事件导致资源的不必要浪费,但是节流 是需要 有效代码会根据固定频率去执行,原理就是定义一个节流阀,在执行的事件当中打开节流阀,最重要的是在下次执行这个事件之前要判断,打开的节流阀是否存在,上次事件还存在的话就停止继续执行等待执行完毕,不存在的话就继续执行。
函数节流 代码解:
看下面节流函数,这里利用定时器演示节流效果,先定义空的定时器timer,如果有timer就中断执行,第一次执行肯定是没有timer,对timer进行定时器赋值,下面就会执行定时器中的请求,定时器中请求完成后对节流阀timer重新放开(这一步是节流的核心),每次请求完成都需要打开节流阀,只有当节流阀 timer 为null时再次点击执行事件才会进行下一次请求事件,否则重复多次点击执行事件时就会先判断之前节流阀是还存在吗,是就中断函数执行
function throttle(foo,delay){
// foo-被执行节流的函数
// 节流的节奏时间间隔
// 初始化timer,并使用闭包访问
let timer;
return function(){
// 若之前已有节流,中断函数执行
if(timer) return;
// 若(之前/此时)无节流,重新设定节流
timer = setTimeout(()=>{
// 暂时理解不了(this,arguments)指向改变的问题
foo.call(this,arguments)
// 本次节流执行后,通过给timer赋值null,释放timer
timer = null
// 不输入延迟 则默认 1000 ms
},delay || 1000)
}
//也可以设置节流阀为布尔值或者是一个变量,通常是布尔值多些
function throttle(fn, delay = 200) {
let flag = true
return function (...args) {
if (!flag) {
return
}
flag = false
setTimeout(() => {
fn.apply(this, args)
flag = true
}, delay)
}
}
要注意的是,防抖和节流返回的都是回调函数,需要先用变量接收,再进行变量的调用。
防抖和节流的区别:
防抖:函数虽然会多次执行 但是有效代码只执行一次
节流:函数虽然会多次执行 但是有效代码只会根据固定频率去执行这是关键区别:
- 防抖有重置概念
- 节流没有重置概念
- 同样有多次执行操作,防抖是将多次变为执行最后一次
- 节流是降低执行频率,变成隔一段时间执行一次
- 防抖每次触发的时候都会先把之前的取消,然后重新执行
- 节流执行的时候需要判断是否等待上次执行的延时函数
应用场景:
函数防抖(debounce):
- search搜索联想,用户在不断输入值时,用防抖来节约请求资源;
- window触发resize或scroll事件的时候,不断的调整浏览器窗口大小会不断的触发这个事件,用防抖来让其只触发一次。
函数节流(throttle):
- 一定时间内多次点击一个功能按钮
- 鼠标不断点击触发,mousedown(单位时间内只触发一次)
- 页面无限加载。需用户滚动页面时,每隔一段时间发一次 ajax 请求,而不是只要滚动就请求数据
-
通过resize,使浏览器页面窗口放大缩小。
部分图 借鉴了掘进的博主文章,非常详细实用
图文结合——详解 js 防抖与节流 - 掘金