傻瓜式手写节流防抖

351 阅读3分钟

理解节流和防抖

节流:游戏里的技能冷却时间

  • 游戏中当玩家按下技能时,对应游戏角色会马上放出技能或经过引导时间放出技能,在技能放出之后,就会进入冷却时间,在这个时间中,无论玩家如何点击该技能都不会再次放出技能,让玩家在冷却时间放不出技能的功能就叫节流

image.png

防抖:游戏里回城过程中再次点击回城(打断回城)

  • 在游戏中当玩家按下回城按钮时,经过一段时间的引导,才能回到泉水进行回血、装备购买等操作,在回城引导的过程中,假如玩家再次点击回城按钮那么就会重新进行回城引导,当玩家回城过程中重新点击回城重新读条以及时间结束后完成回城这个功能就叫防抖

image.png

实现节流和防抖的功能

手写节流

const d = () => {
  console.log("闪现");
};
// d函数就是技能触发效果

let 冷却中 = false;
let 冷却时间 = null;

function sx() {
  if (冷却中) {return}
  d();
  冷却中 = true;
  冷却时间 = setTimeout(() => {
    冷却中 = false;
  }, 120 * 1000);
}

  • 这段代码的含义就是当调用闪现这个功能时,要判断技能是否在冷却中,假如技能未在冷却中则触发技能效果,随后把冷却中置为true代表正在冷却,随后冷却时间开始计时,当计时完成后把冷却中改为false
  • 这只是为了方便理解写的伪代码,在真实开发中实现节流函数应如下
// 定时器实现防抖
const throttle = (f, time, atThis) => {
  let timer = null;
  return (...args) => {
    if (timer) {
      return;
    }
    // 简化了冷却中这个判断条件,直接判断timer是否存在即可
    f.call(atThis, ...args);
    // 假如传进来的函数有参数就把参数原封不动给f作为参数
    timer = setTimeout(() => {
      timer = null;
    }, time);
  };
};

// 使用
const d2 = throttle(console.log('闪现了'), 120 * 1000);
// atThis参数是可选的,如果需要传this就要把箭头函数改为普通函数

手写防抖

const fn = () => {
  console.log("回城成功");
};
// 回城成功时调用

let timer = null;

function x() {
  if (timer) {
    clearTimeout(timer);
  }
  // 回城时检测是否已经在回城,如果已经在回城就把计时器关闭,在下面重新计时
  timer = setTimeout(() => {
    fn();
    // 当3秒钟走完,调用回城成功
    timer = null;
  }, 3000);
}
  • 上述代码的含义是,用户点击回城就开始执行x函数,首先要判断计时器是否存在,假如已经存在则需要把计时器清零,不存在计时器则不做任何事,之后会创建一个计时器,当计时器运行完毕后就让玩家角色触发回城效果
  • 真实开发中防抖写下列代码
const debounce = (f, time) => {
  let timer = null;
  return (...args) => {
    if (timer) {
      clearTimeout(timer);
    }
    timer = setTimeout(() => {
      f(...args);
      // 当3秒钟走完,调用回城成功
      timer = null;
    }, time);
  };
};
// 和节流一样,如果需要this则改变函数为普通函数然后用call或apply把this传进去即可

总结

节流在实际开发中使用场景为:不期待用户频繁点击按钮,就把点击事件节流一下就能让用户在多少秒后才能实现点击事件

防抖在实际开发中使用场景为:当用户频繁拖动窗口或应用大小,期望在停止后一段时间再实现一个效果,就可以用防抖