函数防抖和函数节流学习

109 阅读1分钟

解释

  • 函数防抖(debounce):在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。
  • 函数节流(throttle):规定在一个单位时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有一次生效。

场景

  • 向服务端频繁发请求,增加服务器压力。
  • 频繁dom操作影响浏览器性能

实现

栗子🌰:
function debounce(fn, interval, immediate) {
  //fn为要执行的函数
  //interval为等待的时间
  //immediate判断是否立即执行
  var timeout;  //定时器
  return function () { //返回一个闭包
    var context = this, args = arguments; //先把变量缓存
    var later = function () {  //把稍后要执行的代码封装起来
      timeout = null; //成功调用后清除定时器
      if (!immediate) fn.apply(context, args); //不立即执行时才可以调用
    };
    var callNow = immediate && !timeout;  //判断是否立即调用,并且如果定时器存在,则不立即调用
    clearTimeout(timeout);  //不管什么情况,先清除定时器,这是最稳妥的
    timeout = setTimeout(later, interval);  //延迟执行
    if (callNow) fn.apply(context, args);  //如果是第一次触发,并且immediate为true,则立即执行
  };
};

var throttle = function (fn, interval = 500) { //fn为要执行的函数,interval为延迟时间
  var _self = fn,  //保存需要被延迟执行的函数引用
    timer,  //定时器
    firstTime = true;  //是否第一次调用
  return function () { //返回一个函数,形成闭包,持久化变量
    var args = arguments, //缓存变量
      _me = this;
    if (firstTime) { //如果是第一次调用,不用延迟执行
      _self.apply(_me, args);
      return firstTime = false;
    }
    if (timer) { //如果定时器还在,说明上一次延迟执行还没有完成
      return false;
    }
    timer = setTimeout(function () { //延迟一段时间执行
      clearTimeout(timer);
      timer = null;
      _self.apply(_me, args);
    }, interval);
  };
};