面试题 : 手写节流 throttle、防抖 debounce

66 阅读1分钟

节流就是「技能冷却中」

  • 通过使用闭包和状态变量 冷却中,可以确保在 time 时间内只能触发一次 fn 函数。
  • 节流常见用于处理用户输入、滚动事件等需要控制触发频率的情况。
const throttle = (fn, time) => { 
  let 冷却中 = false 
  return (...args) => { 
    if(冷却中) {return console.log('冷却中')}
    fn.call(undefined, ...args) 
      冷却中 = true 
      setTimeout(()=>{ 
        冷却中 = false 
      }, time) } 
  } 
  
使用方法: const fn = throttle(()=>{console.log('hi')}, 3000) 
          f() // 打印 hi f() // 冷却中
  
  
// 还有一个版本是在冷却结束时调用 fn 
// 简洁版,删掉冷却中变量,直接使用 timer 代替 
const throttle = (f, time) => {
      let timer = null 
      return (...args) => { 
        if(timer) {return console.log('冷却中')} 
        f.call(undefined, ...args) 
        timer = setTimeout(()=>{ 
          timer = null 
      }, time) } 
} 

使用方法: const f = throttle(()=>{console.log('hi')}, 3000) 
          f() // 打印 hi f() // 冷却中

防抖就是「回城被打断」

  • 通过使用闭包和状态变量 回城计时器,可以确保在连续触发事件时只有最后一次触发才会执行 fn 函数,从而实现了防抖的效果。

  • 防抖通常用于处理用户输入、滚动事件等可能频繁触发的情况,以减少不必要的计算和请求。

const debounce = (fn, time) => {
  let 回城计时器 = null 
  return (...args)=>{ 
    if(回城计时器 !== null) { 
      clearTimeout(回城计时器) // 打断回城 
    } 
    // 重新回城 
    回城计时器 = setTimeout(()=>{ 
      fn.call(undefined, ...args) // 回城后调用 fn 
      回城计时器 = null 
    }, time) 
  } 
}