两者对比

  1. 防抖(Debounce) 原理:当事件被触发后,延迟一段时间(比如 300ms)再执行目标函数。如果在这段时间内事件再次被触发,就重新计时,只有当事件停止触发一段时间后,函数才会真正执行。

场景:适合需要“等一等”的情况,比如搜索框输入,用户输入完后再发起请求。

形象记忆:想象你在等人挤电梯。每次有人来(事件触发),你就重新等几秒,确保没人再来时才关门(执行函数)。如果一直有人来,你就一直推迟关门。

  1. 节流(Throttle) 原理:在事件触发时,立即执行函数,但设置一个时间间隔(比如 300ms),在此间隔内即使事件再次触发,函数也不会再次执行,直到下个时间间隔到来。

场景:适合需要“控制频率”的情况,比如滚动监听、鼠标移动,确保函数不会过于频繁执行。

形象记忆:想象你在玩射击游戏,节流就像机关枪的射速限制——每秒只能射一次(固定间隔执行),不管你多快按扳机,子弹发射都有节奏。

防抖节流总结:

  • 防抖函数一般用于表单搜索,点击事件等场景,目的就是为了防止短时间内多次触发事件。

  • 节流函数一般为了降低函数执行的频率,比如滚动条滚动,鼠标跟踪。

debounce

假设你正在乘电梯上楼,当电梯门关闭之前发现有人也要乘电梯,礼貌起见,你会按下开门开关,然后等他进电梯; 如果在电梯门关闭之前,又有人来了,你会继续开门; 这样一直进行下去,你可能需要等待几分钟,最终没人进电梯了,才会关闭电梯门,然后上楼。

  1. debounce 函数会通过闭包维护一个 timer

  2. 当同一 action 在 delay 的时间间隔内再次触发,则清理 timer,然后重新设置 timer

const debounce = (fn, wait) => {
  var timerId = null;

  return function () {
    clearTimeout(timerId);
    timerId = setTimeout(() => {
      fn.apply(this, arguments);
    }, wait);
  };
};

所以 debounce 的作用是,当调用动作触发一段时间后,才会执行该动作,若在这段时间间隔内又调用此动作则将重新计算时间间隔

throttle

假设你正在乘电梯上楼,当电梯门关闭之前发现有人也要乘电梯,礼貌起见,你会按下开门开关,然后等他进电梯; 但是,你是个没耐心的人,你最多只会等待电梯停留一分钟; 在这一分钟内,你会开门让别人进来,但是过了一分钟之后,你就会关门,让电梯上楼。

const throttle = (fn, wait) => {
  var wait = wait || 0;
  var lastTime = 0;

  return function () {
    var currentTime = +new Date();
    if (currentTime > lastTime + wait) {
      lastTime = currentTime;
      fn.apply(this, arguments);
    }
  };
};
function debounce(fn, wait) {
  // 先说下是干啥的 防抖
  var timerId = null;
  // 电梯举例: 加入你坐电梯,你设置时间,在这个时间段内,只要有人按 你就会暂停。这个过程可能需要等待几分钟,最终没人进电梯了
  return function () {
    clearTimeout(timerId);
    timerId = setTimeout(() => {
      fn.apply(this, arguments);
    }, wait);
  };
}
function throttle(fn, wait) {
  // 节流代表的意思是 你是个很没有耐心的人 throttle
  // 这个时间段内 执行多少次 你不管 ,只要超过了 这个时间 你就会走
  var lastTime = 0;
  return function () {
    currentTime = +new Date();
    if (currentTime > lastTime + wait) {
      lastTime = currentTime;
      fn.apply(this, arguments);
    }
  };
}
function debounce(fn, wait) {
  let timerId = null;
  return function () {
    clearTimeout(timerId);
    timerId = setTimeout(() => {
      fn.apply(this, arguments);
    }, wait);
  };
}
function throttle(fn, wait) {
  var waite = wait || 0;
  var lastTime = 0;
  return function () {
    var currentTime = +new Date();
    if (currentTime > lastTime + waite) {
      lastTime = currentTime;
      fn.apply(this, arguments);
    }
  };
}
//去抖动
const debounce = (fn, wait) => {
  var timerId = null;

  return function () {
    if (timerId) {
      clearTimeout(timerId);
    }
    timerId = setTimeout(() => {
      fn.apply(this, arguments);
    }, wait);
  };
};
// 节流
const throttle = (fn, wait) => {
  var lastTime,
    wait = wait || 0;
  return function () {
    var currentTime = +new Date();
    if (currentTime - lastTime > wait) {
      lastTime = currentTime;
      fn.apply(this, arguments);
    }
  };
};

最后更新于

这有帮助吗?