JS节流与防抖

JS节流和防抖是说的非常多一个话题,不论什么时候,

不然会来带很多性能问题。

节流

实现函数节流throttle的方法一般有两种:

  • 定时器setTimeOut

  • 时间戳new Date()

定时器方式

function throttle(fn, time) {
  let timer;
  return function(){
    const args = arguments;
    const _that = this;
    if(timer) {
      return;
    } 
    timer = setTimeOut(() => {
      fn.call(_that, args);
      timer = null;
    }, time);
  }
}

或者两者组合起来使用,更加精确

定时器+时间戳方法

// 简单的节流函数 wait的延时保证程序的健壮性
function throttle (func, mustRun, wait) {
  let timeout,
  startTime = new Date().getTime();
  return function () {
    let that = this,  
      args = arguments,
      curTime = new Date().getTime();
    clearTimeout(timeout);
    // 如果达到了时间间隔,触发 handler
    // 如果没有,设置一个延时,假设为最后一次
    if (curTime - startTime >= mustRun) {
      func.apply(that, args);
      startTime = curTime;
    } else {
      // 没达到触发间隔,重新设定定时器 ,
      // 保证不丢失最后一次触发,如果中间再触发,会在之前被clear掉
      timeout = setTimeout(func, wait);
    }
  };
}

测试

let timer1 = setInterval(throttle(fn, 500), 10); // 每500ms执行一次

防抖

当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前,又一次触发了事件,就重新开始延时。

function debounce(fn, wait) {
  var timer = null;
  return function () {
    var context = this
    var args = arguments;
    clearTimeout(timer);
    timer = setTimeout(function () {
      fn.apply(context, args)
    }, wait);
  }
}

测试:设置一个定时器,每10ms执行一次,1s后关闭。 debounce防抖时间设置为500ms,则函数应该在1.5s后执行

console.time('debounce')
let fn = function () {
  console.timeEnd('debounce', ‘’)
}

let timer1 = setInterval(debounce(fn, 500, true), 10);
let timer2 = setTimeout(() => { clearInterval(timer1) }, 1000);
// 函数被执行
// debounce: 1512.098ms

Last updated