节流throttle、防抖debounce

153 阅读2分钟

面试要点

节流

  • 概念:单位事件内,频繁触发事件,只执行一次
  • 典型场景:高频事件(快速点击、鼠标滑动、scroll事件、resize事件)
  • 代码实现思路:利用定时器,等定时器执行完毕,才开启定时器。

防抖

  • 概念:单位事件内,频繁触发事件,只执行最后一次
  • 典型场景:搜索框搜索输入
  • 代码实现思路:利用定时器,每次触发先清掉以前的定时器。

lodash库

开发中一般用lodash库,利用里面的throttle(节流)和debounce(防抖)来实现的

什么是节流、防抖

节流就是指,连续触发事件但是在设定的一段时间内中只执行一次函数。(不用打断我)

节流就是 技能冷却中,其作用是为了避免用户频繁点击按钮,比如发送验证码;

防抖就是指,连续触发事件但是在设定的一段时间内中只执行最后一次。(从新开始)

防抖就是 回城被打断。其作用是为了避免用户频繁拖拽页面操作,停止后实现某个效果。

应用场景

防抖:

  1. 搜索框搜索输入
  2. 文本编辑器实时保存

节流:

  1. 高频事件(快速点击、鼠标滑动、scroll事件、resize事件)
  2. 下拉加载
  3. 视频播放记录时间

代码实现思路

防抖:利用定时器,每触发一次,都将计时器清空,再执行新的定时器。

手写节流

// v1.0
const d = () => {console.log('闪现')};
let 冷却中 = false;
let timer = null;

function sx(){
  if(冷却中){return};
  d();
  冷却中 = true;
  timer = setTimeout(()=>{
    冷却中 = false
  }, 120*1000)
}
// v2.0
const d = () => {console.log('闪现')};

const throttle = (f, time) => {
  let 冷却中 = false;
  let timer = null;
  return (...argus) => {
    if(冷却中){return};
    f(...argus);
    冷却中 = true;
    timer = setTimeout(()=>{
      冷却中 = false
    }, time)
  }
} 

const d2 = throttle(d, 120*1000);
d2() // 120s 之后才会打印出 闪现,中途调用d2,没有任何效果

手写防抖

// v1.0
const f = () => {console.log('回城成功')};

let timer = null;

function x(){
  if(timer){  // 再次调用 x
    clearTimeout(timer)
  }
  timer = setTimeout(() => {
    f()
    timer = null;
  }, 3000)
}
// v2.0
const f = () => {console.log('回城成功')};

const debounce = (f, time) => {
  let timer = null;
  return (...args)=>{
    if(timer){  // 再次调用 x
      clearTimeout(timer)
    }
    timer = setTimeout(() => {
      f(...args)
      timer = null;
    }, time)
  }
}
const tp = debounce(f, 3000);
tp()  // 3s 后打印出 回城成功; 中途强制打断他后 需要 3s 后打印出回城成功