# 防抖
什么是防抖,在操作系统中如果一块数据在短时间内频繁地由内存换出到外存,再由外存换入内存。这种内存频繁进行换入换出的现象我们称之为内存抖动。类似的在前端中,如果一个页面过于地进行频繁地触发事件我们也将这种行为称之为抖动。
防抖策略(debounce)是当事件被触发后,延迟 n 秒后再执行回调,如果在这 n 秒内事件又被触发,则重新计时。
防抖最典型的应用例子就是我们在淘宝上进行商品搜索的时候,每当我们输入一个关键字,搜索框下面就会弹出相应关键字的搜索结果。
这里如果我们设置的是每当用户弹起键盘我们就发送一次 ajax 请求去刷新数据,那么在输入过程中就会导致太多的 ajax 请求被发送,造成抖动。所以我们需要减少一些不必要的网络请求来减轻服务器压力。
原理演示代码
// 设置一个定时器记录 | |
let timer = null | |
ipt.addEventListener('keyup',function(){ | |
// 每次键盘按下就清除定时器,延迟触发 | |
if(timer) clearTimeout(timer); | |
// 设置 200ms 后触发事件 | |
timer = setTimeout(function(){ | |
/* 进行相应操作 */ | |
},200) | |
}) |
代码实现及其使用
const target = document.getElementById(id); | |
function debouch(callback,delay = 100){ | |
let timer = null; | |
return function(){ | |
if(timer){ | |
clearTimeout(timer); | |
} | |
timer = setTimeout(()=>{ | |
callback.apply(this,arguments); | |
timer = null; | |
},delay); | |
} | |
} | |
function add(a,b){ | |
return a + b; | |
} | |
target.addEventListiner('click',debouch(add,300)) |
# 节流
和防抖类似减少事件触发的概念就是节流,节流的目的是让事件在规定的时间间隔内只能触发一次。和操作系统里同步问题使用互斥锁的思想类似。我们可以在触发某类事件时,先让它判断目前是否可以进入,若可以进入就让它进入后立即将 flag 置为 false 使后续事件不能继续进入,退出前在将 flag 置为 true。
节流策略(throttle),顾名思义,可以减少一段时间内事件的触发频率。
节流最典型的应用就是懒加载时要监听计算滚动条的位置,但不必每次滑动都触发,可以降低计算的频率,而不必去浪费 CPU 资源
原理演示代码
// 定义一个节流阀 | |
let timer = null; | |
btn.addEventListener('click',function(){ | |
if(timer){ | |
return 0; | |
} | |
timer = setTimeout(function(){ | |
/* 进行相应操作 */ | |
timer = null; | |
},1000) | |
}) |
代码实现及使用
const target = document.getElementById(id); | |
function throttle(callback,delay = 100){ | |
let timer = null; | |
return function(){ | |
if(timer){ | |
return 0; | |
} | |
timer = setTimeout(()=>{ | |
callback.apply(this,arguments); | |
timer = null; | |
},delay) | |
} | |
} | |
function add(a,b){ | |
return a + b; | |
} | |
target.addEventListiner('click',thrrotle(add,300)) |
# 总结
防抖:如果事件被频繁触发,防抖能保证只有最后一次触发生效,前面 N 多次的触发都会被忽略!
节流:如果事件被频繁触发,节流能够减少事件触发的频率,因此,节流是有选择性地执行一部分事件!