**节流与防抖: 防止函数多次调用。**都是用于**避免用户在规定的事件内多次点击导致多次处理**数据(多次发送请求)。将多次请求合并的一个策略。
节流: 一个函数在执行一次后, 只有大于设定的执行周期才会执行第二次。
高频事件触发,但在n秒内只会执行一次,所以节流会稀释函数的执行频率
实现1: 有个需要频繁触发得到函数, 在规定时间内,只让函数触发的第一次生效。后面不不生效。
/**
* 节流函数
* @param fn 要被节流的函数
* @param delay 规定的时间周期
*/
function throttle(fun, delay) {
var lastTime = 0; // 记录上一次被触发的时间
return function(){
var nowTime = new Date(); //记录当前触发函数的时间
if(nowTime -lastTime > delay){
fun.apply(this); //修正this的指向
lastTime = nowTime; //同步时间
}
}
}
**实现2:**每次触发事件时,如果当前有等待执行的延时函数,则直接return
//节流throttle代码:
function throttle(fn) {
let canRun = true; // 通过闭包保存一个标记
return function () {
// 在函数开头判断标记是否为true,不为true则return
if (!canRun) return;
// 立即设置为false
canRun = false;
// 将外部传入的函数的执行放在setTimeout中
setTimeout(() => {
// 最后在setTimeout执行完毕后再把标记设置为true(关键)表示可以执行下一次循环了。
// 当定时器没有执行的时候标记永远是false,在开头被return掉
fn.apply(this, arguments);
canRun = true;
}, 500);
};
}
防抖: 一个需要频繁触发的函数, 在规定时间内, 只让最后一次生效,前面的不生效。
将多次操作合并为最后一次操作进行。
原理: 维护一个计时器,规定在delay时间后触发函数,但是在delay时间内再次触发的话,就会取消之前的计时器而重新设置。这样一来,只有最后一次操作能被触发。
**缺点:**如果事件在规定的时间间隔内被不断的触发,则调用方法会被不断的延迟。
实现: 每次触发事件时设置一个延迟调用方法,并且取消之前的延时调用方法.
function debounce(fun, delay){
let time = null; //设置上一次的定时器
return function(){
if(time){ //当存在定时器, 则清除上一次的定时器
clearTimeout(timer);
}
timer = setTimeout(function(){//重新设置新的定时器
fun.apply(this);
}, delay)
}
}
区别: 函数节流不管事件触发有多频繁,都会保证在规定时间内一定会执行一次真正的事件处理函数,而函数防抖只是在最后一次事件后才触发一次函数