手写一个节流函数

207 阅读2分钟

手写一个节流函数

  1. 什么是函数节流: 函数节流是指在一定的时间间隔内 只执行一次,在这三秒内无视产生的函数调用请求,也不会延长时间间隔

  2. 场景: 适合函数被调用的特别频发,例如window.onresize();

  3. 方案:

    • 方案1: 利用时间戳来判断是否已经到了执行的时间。记录上次执行的时间戳,然后每次触发事件执行回调,回调中判断当前时间戳距离上次执行时间戳的间隔是否已经达到了时间差值,也就是等待时间,如果是,则执行函数,并更新执行时间,如果不是则无视。

      // 需要利用闭包
      /**
      * @description 节流函数
      * @param { Function } fn:  时间到时要执行的回调函数
      * @param { number } wait: 时间间隔 默认值为1000ms 
      */
      const throttle = (fn, wait = 1000) => {
          var previous = 0;  // 闭包变量,类似于外面的全局变量,内部的函数可以访问到,用于保存上次触发的时间
          return function (...args) {
              // 获取函数的执行时间,将时间转为时间戳
              let now = +new Date();
              // 将 now 和 previous 进行差值计算,如果大于wait 时间,就触发回调函数
              if(now - previous > wait){
                  // 将执行时间赋值给previous
                  previous = now;
                  fn.apply(this.args);
              }
          }
      }
      
      
      //es6
      
      const throttle = (fn, wait) => {
          let privous = 0;
          return (...args) => {
              let now = +new Date();
              if(now - privous > wait){
                  privous = now;
                  fn(args);
              }
          }
      }
      
    • 方案2: 利用定时器,当触发事件的时候,生成一个定时器,设置好时间,然后执行定时器,如果在次触发的时候,定时器存在则无视,如果定时器不存在,则重新生成一个定时器,也就是说在定时器执行成功之后,将定时器销毁。

      // 还是利用闭包的方式
      function throttle (fn, wait) => {
          let a = null;
          return function(){
              if (!a){
                 a = setTimeout()  
              }
          }
      }