导航


HTML

CSS

JavaScript

浏览器 & 网络

版本管理

框架

构建工具

TypeScript

性能优化

软实力

算法

UI、组件库

Node

冷门技能

针对性攻坚(TODO)


防抖

用户动作停止后,延迟 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 = false) {
  let timer = null;
  let called = false; // 控制是否已经立即触发过

  return function () {
    const context = this;
    const args = arguments;

    if (triggerNow && !called) {
      fn.apply(context, args);
      called = true;
    }

    if (timer) clearTimeout(timer);

    timer = setTimeout(() => {
      if (!triggerNow) {
        fn.apply(context, args);
      }
      timer = null;
      called = false; // 重置状态,下一轮调用可以再次立即触发
    }, delay);
  };
}

应用

节流

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

理解:

  1. 打游戏技能cd,按一下立即释放,但有冷却时间,此时间段内再按多少次都无效,直到cd转好
  2. 在单位时间内无论触发多少次,我只执行1次

核心

实现

function throttle(fn, delay) {
	let canUse = true;
  return function() {
    if (canUse) {
    	fn.apply(this, arguments);
      canUse = false;
      setTimeout(() => canUse = true, delay);
    }
  }
}

应用