# 函数节流

# 含义

当持续触发事件时,保证一定时间段内只调用一次事件处理函数

# 实现

# 定时器实现


  const throttle = function(fn ,delay) {
    let tag = false;
    const throttle = function(...arg) {
      if (tag) return;
      tag = true;
      setTimeout(() => {
        tag = false;
        fn.apply(this, arg);
      }, delay);
    }
    return throttle;
  }

# 时间戳实现


  const throttle = function(fn, delay, immediate) {
    let lastTime = 0, result;
    const throttle = function(...arg) {
      const now = Date.now();
      if (now - lastTime > delay) {
        result = fn.apply(this, arg);
        lastTime = now;
      }
    }
    return throttle;
  }

# 定时器+时间戳实现,及示例

  <!DOCTYPE html>
  <html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>节流</title>
    <style>
      #square{
        width: 1000px;
        height: 1000px;
        background-color: #014601;
      }
    </style>
  </head>
  <body>
    <div id="square"></div>
  </body>
  <script>
    // 时间戳+定时器
    const throttle = function(fn, delay, options) {
      let lastTime = 0, timer = null, result;
      const throttle = function(...arg) {
        const now = Date.now();
        if (!lastTime && options.start === false) lastTime = now;
        const deferTime = delay - (now - lastTime);
        if (deferTime <= 0 || deferTime > delay) {
          if (timer) {
            clearTimeout(timer);
            timer = null;
          }
          result = fn.apply(this, arg);
          lastTime = now;
        } else {
          if (!timer && options.end !== false) {
            timer = setTimeout(() => {
              result = fn.apply(this, arg);
              // 重要,既然执行了,则重置时间
              lastTime = options.start === Date.now();
            }, delay);
          }
        }
        return result;
      }
      return throttle;
    }
    function test(a) {
      console.log(a);
    }
    const square = document.getElementById('square');
    square.onmousemove = throttle(test, 1000, {
      start: false, // 是否进去立即执行一次
      end: false // 是否执行最后一次,延迟一段时间
    });
  </script>
  </html>

# 用途

  • 监听滚动事件,需要规律时间间隔执行某些事件时
  • 当输入框不断输入内容,根据输入内容做接口匹配时,避免重复不断调用,在固定时间间隔进行访问接口时

注意

防抖和节流的对比: 防抖只会执行一次,节流是固定时间间隔不断执行