面试必会的几种防抖写法,足以回答面试官的问题

117 阅读2分钟

前言:

最近在面试中经常遇到一些面试官要求手写防抖,写出来还要在上面加一点功能。趁着空闲时间赶紧总结了一下几种写法,希望能够帮助小伙伴们在求职或者在工作中能用上~

防抖写法:

基本版(绑定this+传参)

要求: 当触发一个事件时,延迟 n 秒后执行相应的操作。如果在这 n 秒内再次触发该事件,会以最新的触发时间为准,重新计时 n 秒后执行操作。换句话说,只有在触发事件后的 n 秒内没有再次触发事件,才会执行操作。

/**
 * 防抖
 * @param {Function} fn 添加防抖的事件
 * @param {Number} delay 延迟毫秒
 */
function debounce(fn, delay){
  let timer;
  return function() {
    let context = this;
    let args = arguments;
    
    clearTimeout(timer);
    timer = setTimeout(() => {
      func.apply(context, args)
    },delay)
  }
}

//测试代码,可以直接贴在控制台运行
function task(){ 
  console.log('run task') 
} 
const debounceTask=debounce(task,1000) 
window.addEventListener('scroll',debounceTask);

立即执行版

要求: 无需等待事件停止触发后才执行操作,而是在触发事件后立即执行操作,然后在停止触发 n 秒后才能重新触发执行。

/**
  * 防抖(立即执行版)
  * @param {Function} fn 添加防抖的事件
  * @param {Number} delay 延迟毫秒
*/
function debounce(fn,wait){ 
  let timerId = null; 
  let flag = true; 
  return function(){
    clearTimeout(timerId); 
    if(flag){ 
      fn.apply(this,arguments); 
      flag = false 
    } 
    timerId = setTimeout(() => {
      flag = true
    },wait) 
  } 
}

//测试代码,可以直接贴在控制台运行
function task(){ 
  console.log('run task') 
} 
const debounceTask=debounce(task,1000,true) 
window.addEventListener('scroll',debounceTask);

立即执行+取消防抖版

要求: 假设防抖的时间间隔为 10 秒,且 immediate 为 true。这意味着只有等待 10 秒后才能重新触发事件。现在添加一个取消等待的功能,一旦执行该功能,防抖将被取消,这样就可以立即再次触发事件并执行操作。

/**
 * 防抖(立即执行+取消防抖版)
 * @param {Function} func 添加防抖的事件
 * @param {Number} wait 延迟毫秒
 * @param {Boolean} immediate 是否是立刻执行
 */
function debounce(func, wait, immediate) {
  let timeout;

  let debounced = function () {
    let context = this;
    let args = arguments;

    if (timeout) clearTimeout(timeout);
    if (immediate) {
      let canDoNow = !timeout;
      timeout = setTimeout(function () {
        timeout = null;
      }, wait);
      if (canDoNow) func.apply(context, args);
    } else {
      timeout = setTimeout(function () {
        func.apply(context, args);
      }, wait);
    }
  };

  // 取消函数
  debounced.cancel = function () {
    clearTimeout(timeout);
    timeout = null;
  };

  return debounced;
}

如果有其他小伙伴还碰到其他的防抖写法,可以在评论区说交流一下,共同进步呀~