防抖
什么是防抖
频发触发某个事件,一定时间内没有再次触发,则只执行最后一次。如果规定时间内再次执行就重新开始计时。
防抖业务场景
比如搜索输入框,如果用户每次输入一个字符就发送一次请求,请求发送过于频繁。因此在用户停止输入的N秒以后发送请求。
手写防抖原理
- 定义函数,接收事件函数fn和防抖的规定等待时间wait
- 定义一个定时器
- 防抖函数的返回结果为一个函数。函数内部是fn的执行结果,使用apply方法将fn的执行上下文改为return的函数,并且传入参数。
- 使用settimeout延迟执行这个函数。
- 并且如果已经有定时器在执行这个函数,就清除定时器,保证函数只执行一次。
代码实现
function debounce(fn,wait){
let timer;
return function(){
if(timer)clearTimeout(timer)
timer = setTimeout(()=>{
fn.apply(this,arguments);
},wait)
}
}
节流
什么是节流
将事件的频繁触发改为少量触发。执行一次以后,只有超过设定时间后再次触发才会执行下一次。
节流业务场景
- 项目中,三级联动中,能够点击的选项过多,因此每次点击都会加载相应的组件。如果用户点击过快,浏览器没有足够时间解析,引发卡顿。
- 或者一些频繁触发事件,onmousemove,鼠标滚动事件(scroll),窗口调整resize,疯狂抢购点击(click)。触发频率非常高,这时如果还伴随着向后台发送请求,会对服务器造成不必要的压力,还会造成页面卡顿
手写节流
第一种实现方式,利用时间戳
function throttle(fn, wait) {
let previous = 0
return function () {
let now = Date.now();
if (now - previous > wait) {
fn.apply(this, arguments);
previous = now;
}
}
}
第二种实现方式,利用定时器实现
function throttle(fn,wait){
let timer = null
return function(){
if(!timer){
timer = setTimeout(()=>{
fn.apply(this,arguments)
timer = null
},wait)
}
}
}