防抖

用户动作停止后,延迟 n 秒再执行事件处理函数

理解:

  1. 外卖在店家门口等订单,如果1分钟之内,又来了一单该店家的,就再等1分钟,如果再来,就再等... 直到超过1分钟后,就开始送
  2. 公交车刷卡,一直刷一直刷,等到最后一次刷完等待多长时间没有再次刷卡后,车开走

核心

实现

function debounce(fn, delay) {
  let timer = null;
	return function() {
    if (timer) window.clearTimeout(timer);
  	timer = setTimeout(() => {
    	fn.apply(this, arguments);
      timer = null; // 当一个对象被赋值了null 以后,原来的对象在内存中就处于游离状态,GC 会择机回收该对象并释放内存。因此,如果需要释放某个对象,就将变量设置为null,即表示该对象已经被清空,目前无效状态。
    }, delay);
  }
}

如果希望事件触发时立即执行,可加个 triggerNow 参数:

function debounce(fn, delay, triggerNow) {
	let timer = null;
  return function() {
  	if (timer) window.clearTimeout(timer);
    if (triggerNow) {
    	let exec = !timer;
      timer = setTimeout(() => {
      	timer = null;
      }, delay);
      if (exec) {
      	fn.apply(this, arguments);
      }
    } else {
    	timer = setTimeout(() => {
      	fn.apply(this, arguments);
        timer = null;
      }, delay);
    }
  }
}

应用

节流

用户动作时, n 秒内只执行一次事件处理函数