防抖\节流

41 阅读1分钟

理解

  • 防抖是将多次执行变为只执行一次,节流是将多次执行变为每隔一段时间执行

参考

源码

防抖

function debounce(func, delay) {
  let timeout;
  return function() {
    const context = this;
    const args = arguments;
    clearTimeout(timeout);
    timeout = setTimeout(() => func.apply(context, args), delay);
  };
}
function debounce(fn, wait) {
  var timeout = null;// 使用闭包,缓存变量  return function() {
        if(timeout !== null) {
          console.log('清除定时器啦')
          clearTimeout(timeout);  //清除这个定时器
        }
        timeout = setTimeout(fn, wait);
    }
  }
// 暴力版: 定时器期间,有新操作时,清空旧定时器,重设新定时器
function debounce(fn, wait){
    let timer;
    return function(){
        // 如果 timer 存在则表示当前还在周期内,需要清空旧的定时器创建新的定时器
        if(timer){
            clearTimeout(timer);        }
        // 创建定时器,用于在周期结束后执行函数逻辑
        timer = setTimeout(()=>{
            fn.apply(this, arguments);
            clearTimeout(timer);
            timer = null;
        },wait);
    }
}

节流

function throttle(func, delay) {
  let wait = false;

  return (...args) => {
    if (wait) {
        return;
    }

    func(...args);
    wait = true;
    setTimeout(() => {
      wait = false;
    }, delay);
  }
}
var throttle = function(func, delay) {
    var timer = null; // 使用闭包,缓存变量
    var prev = Date.now(); // 最开始进入滚动的时间
    return function() {
      var context = this;   // this指向window
      var args = arguments;
      var now = Date.now();
      var remain = delay - (now - prev); // 剩余时间
      clearTimeout(timer);
      // 如果剩余时间小于0,就立刻执行
      if (remain <= 0) {
        func.apply(context, args);
        prev = Date.now();
      } else {
        timer = setTimeout(func, remain);
      }
    }
  }
function throttle (fn, wait) {
    let timer;
    let context, args;

    return function () {
        context = this;
        args = arguments;
        // 如果不存在 timer 表示当前不在周期内
        if (!timer) {
            // 开始一个新周期
            timer = setTimeout(() => {
                fn.apply(context, args);
                // 周期结束
                clearTimeout(timer);
                timer = null;
            }, wait);
        }
    }
}