简单实现防抖和节流

1,418 阅读3分钟

为什么会用到防抖和节流呢?

举个例子

假如我们开发了一个活动,用户量也比较大,网络环境也不是很好的情况下,用户点击操作的时候,如果我们不限制,可能会出现大量的请求,导致我们的服务压力变得很大;
再比如用户在进行奖品兑换或者是其他的操作的时候,如果我们没有限制用户频繁操作,可能会出现一种现象,第一发出去的请求还没有返回结果的情况下用户已经操作第二次了,这个时候,很有可能会出现第一次请求刚成功第二次请求也过去了,这时候可能会返回报错也或者是提示错误之类的; 所以这个时候我们就需要用到防抖与节流的功能;

防抖

什么是防抖呢?

防抖是用来干嘛的?
防抖是为了防止用户过于激动或者手速比较快的时候连续操作,导致频繁触发做的一个限制;

/**
* fn             需要执行的方法
* delay          延时时间,默认给个300毫秒,可以根据需求自己设置
*/  
const debounce = function(fn, delay = 300) {
    let timer = null;
    
    return function() {
        // 除第一次操作以外,如果发现了定时器就清除
        if (timer) clearTimeout(timer);

        timer = setTimeout(function() {
            fn();
        }, delay)
    }
}

上边就是一个简单地防抖方法,能用吗?能用,但是会有些问题;
1.如果传参数怎么办?
2.当前执行对象的方法和事件怎么操作?
3.如果想要点击的时候就立即执行可以吗?
所以需要稍微的改动下

/**
* fn             需要执行的方法
* delay          延时时间,默认给个300毫秒,可以根据需求自己设置
* isImmediately  是否立即执行,默认不会
*/  
const debounce = function(fn, delay = 300, isImmediately = false) {
    let timer = null;
    
    return function() {
        const that = this; // 存储一下当前的this指向
        const args = arguments; // 拿到传递的参数信息
        
        if (timer) clearTimeout(timer);
        
        if (isImmediately) {
            let callNow = !timer; // 根据当前的定时器信息来决定要不要立即执行
            
            timer = setTimeout(function() {
                timer = null;
            }, delay);
            
            if (callNow) {
                fn.apply(that, args);
            }
        } else {
            timer = setTimeout(function() {
                fn.apply(that, args);
            }, delay)
        }
    }
}

节流

什么是节流呢?

节流可以用来干嘛呢?
节流可以理解为是一个控制器的阀门,比如输入框查询的时候,可以不做实时搜索,那样可能会发送很多个请求,可以使用节流的方式,隔段时间发一次;

/**
* fn             需要执行的方法
* delay          延时时间,默认给个300毫秒,可以根据需求自己设置
* isImmediately  是否立即执行,默认不会
* 第一种setTimeout写法
*/

const throttle = function(fn, delay = 300, isImmediately = false) {
  let timer = null;
  
  return function() {
      const that = this; // 存储一下当前的this指向
      const args = arguments; // 拿到传递的参数信息
      
      if (isImmediately) {
        fn.apply(that, args);
        isImmediately = false;
        timer = setTimeout(() => {
          isImmediately = true;
          timer = null;
        }, delay);
        return;
      }
      
      if (!timer) {
        timer = setTimeout(function() {
          fn.apply(that, args);
          timer = null;
        }, delay)
      }
  }
}

/**
* fn             需要执行的方法
* delay          延时时间,默认给个300毫秒,可以根据需求自己设置
* isImmediately  是否立即执行,默认不会
* 第二种时间戳写法
*/

const throttle = function(fn, delay = 300, isImmediately = false) {
  let time = 0;
  
  return function() {
      if (!time) {
          time = Date.now();
          if (isImmediately) {
            fn.apply(this, arguments);
          }
          return;
      }
      if (Date.now() - time > delay) {
          fn.apply(this, arguments);
          time = Date.now();
      }
  }
}

以上就是本次内容,使用哪一种还是需要根据业务中的需求选择;
感谢您的浏览;