防抖就是将函数的指定间隔内的多次执行变成一次,而节流是在间隔时间内必须且只能执行一次。虽然结果差不多,但是原理并不同,而且有细微的区别
防抖的实现
function debounce(fn,delay=1000){
// timer是定时器序号
let timer = null;
return function(...args){
if(timer) clearTimeout(timer)
timer = setTimeout(()=>{
fn.apply(this,args)
},delay);
}
}节流的实现
function throttle(fn,delay=2000){
let [lastTime,deferTimer]=[null,null];
return function (...args) {
let now = +new Date()
if(lastTime&&now<lastTime+delay){
clearTimeout(deferTimer);
deferTimer=setTimeout(()=>{
lastTime = now
fn.apply(this,args)
},delay)
} else {
lastTime = now;
fn.apply(this,args)
}
}
}测试效果
<div>普通的input<input type="text" id="normal"></div> <div>防抖的input<input type="text" id="debounce"></div> <div>节流的input<input type="text" id="throttle"></div>
//模拟ajax
function ajax(content) {
console.log('ajax request ' + content)
}
let inputa = document.getElementById("normal");
inputa.addEventListener('keyup', function (e){
ajax(e.target.value)
});
// 在2s内没有输出才会执行函数。
// 但如果在2s停止输出然后又开始输出,计时器会重新开始计时
let debounceAjax = debounce(ajax)
let inputb = document.getElementById("debounce");
inputb.addEventListener('keyup',function (e){
debounceAjax(e.target.value)
});
// 无论你怎么干2s内只会执行一次
let throttleAjax = throttle(ajax);
let inputc = document.getElementById("throttle");
inputc.addEventListener('keyup', function(e){
throttleAjax(e.target.value)
})