防抖和节流函数

防抖就是将函数的指定间隔内的多次执行变成一次,而节流是在间隔时间内必须且只能执行一次。虽然结果差不多,但是原理并不同,而且有细微的区别

防抖的实现

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" ></div>
<div>防抖的input<input type="text" ></div>
<div>节流的input<input type="text" >//模拟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)
})