理解
防抖
防抖(Debounce):指在一定时间内,如果事件被多次触发,只执行最后一次操作。
节流
节流(Throttle):指在一定时间内,如果事件被多次触发,只执行第一次操作。
方便理解,以现实生活举例(这个例子也是我学习的时候,学习前辈的文章感觉最能让我理解的例子),例如:坐电梯,如果设置电梯从人进入电梯到关门时间为10s,那么防抖就是,第一个人进入,电梯关门要10s,那在这期间又进入电梯一个人,那关门时间就要重新计算,从最后一个进入电梯的人开始计算到关门需要10s,也就是从第一个人进入电梯到关门是大于10s的;节流就是第一个人进入,电梯关门要10s,中间不管进入几个人,10s电梯门就会关,也就是从第一个人进入电梯到关门就只有10s。
解决
防抖
原理就是,在规定时间内不再触发该事件才会执行。即设定一个时间周期延迟执行动作,若该期间又被触发,则重新设定周期,直到时间周期结束才执行动作。
第一个方法:不停重置定时器。缺点:高频的创建定时器
定时器期间,有新操作时,清空旧定时器,重设新定时器
function debounce(fn, cycle) => { //fn:需要执行的操作,cycle:时间周期
let timer, timeStamp=0;
let _this, args;
//创建定时器执行方法的操作
function runFn(){
timer= setTimeout(()=>{
fn.apply(_this,args);
},cycle);
}
//清除定时器
let clean = () => {
clearTimeout(timer);
}
return function(){
_this=this;
args=arguments;
let now = (new Date()).getTime();
if(now-timeStamp < cycle){
//时间周期没到,清除定时器,重新计算时间,创建定时器方法
clean();
run();
}else{
run();
}
timeStamp=now;
}
}
节流
规定时间内只运行一次,若在 时间内重复触发,只有一次生效。
第一个方法:通过时间戳实现
function throttle(fn,cycle) {
//定义初始时间
var startTime=0;
return function() {
var _this=this;
var args=arguments;
//当前时间戳
var newTime = new Date();
//判断用当前时间减去开始的时间,如果大于cycle指定的时间就会触发
if(newTime-startTime>cycle) {
//执行触发的函数
fn.apply(_this,args)
//将开始时间更新
startTime=newTime;
}
}
应用
防抖::
search搜索联想,用户在不断输入值时,用防抖来节约请求资源。
节流:
鼠标不断点击触发,mousedown(单位时间内只触发一次),例如表单的提交。
window触发resize的时候,不断的调整浏览器窗口大小会不断的触发这个事件,用防抖来让其只触发一次。