函数的防抖与节流

1,764 阅读2分钟

title: 函数的节流与防抖 date: 2019-12-26 14:00:00 tabs:

  • 节流
  • 防抖
  • JavaScript categories: Web前端 urlname: throttle&debounce

在前端开发中,有诸如scroll、resize等高频触发事件,如果给事件绑定一个函数, 那么就会频繁的调用一个函数无数次,这样会造成一些性能上的问题,而节流和防抖则用来限制事件触发后 函数的执行次数。

节流

顾名思义节制水流,如果将事件触发喻为水流,那么函数节流则是节制函数触发次数, 即连续触发事件但是只在n秒钟执行一次函数。主要应用于scroll、resize等事件,比如根据scroll滚轮事件判断元素位置并改变css等。

定时器版

const throttle = (func:Function, wait:number) => {
  // 定时器
  let executeTimer = null;
  return (...args:any[]) => {
    if (!executeTimer) {
      // 定时器不存在时执行函数
      func(...args);
      // 赋值定时器
      executeTimer = setTimeout(() => {
        // wait毫秒后赋值为null
        executeTimer = null;
      }, wait);
    }
  }
}

时间戳版

const throttle = (func:Function, wait:number) => {
  let previous = 0;
  return (...args:any[]) => {
    const now = Date.now();
    if (now - previous > wait) {
      func(...args);
      previous = now;
    }
  }
}

防抖

防抖是指触发事件后在n秒内函数只能执行一次,如果在n秒内又触发了事件,则会重新计算函数执行时间。

就是说只要在n秒内不停触发事件,那么就会不停重置执行时间。

比较经典的例子就是input的onChange事件,往往会有需求要求在用户输入文字后进行数据搜索请求, 如果不进行防抖处理,会出现用户每输入一个字都会触发一次请求,我们可以使用防抖函数避免这种情况, 只要在一定时间内输入文字就不会执行搜索请求,直到用户输入最后一个字的n秒后。

立即执行版

指触发事件后立即执行一次函数,如果在n秒内未再次触发事件,那么则会再次执行一次函数。适用于按钮的防抖等。

const debounce = (func:Function, wait:number) => {
  let timer = null;
  return (...args:any[]) => {
    if (!timer) {
      func(...args);
      timer = setTimeout(() => {
        timer = null;
      }, wait);
    }
  }
}

非立即执行版

非立即执行版的意思是触发事件后函数不会立即执行,而是在n秒后执行,如果在n秒内又触发了事件, 则会重新计算函数执行时间。适用于input的onChange事件。

const debounce = (func:Function, wait:number) => {
  let timer = null;
  return (...args:any[]) => {
    if (!timer) {
      timer = setTimeout(() => {
        func(...args);
        timer = null;
      }, wait);
    }
  }
}

参考