js笔记-节流函数

87 阅读1分钟

什么是节流函数:是指在一段时间内限制执行的函数

节流函数实现01:基本实现
function throttle(fn, interval) {
  let lastTime = 0

  const _throttle = function() {
    const nowTime = new Date().getTime() 
    // 用间隔时间减(现在的时间减过去的时间),如果小于0则执行,执行时过去的时间赋值成当前时间
    const remainTime = interval - (nowTime - lastTime)
    if(remainTime <= 0) {
      fn()
      lastTime = nowTime
    }
  }
  return _throttle
}
节流函数实现02:增加了第一次输入时否触发参数和最后一次是否触发参数
function throttle(fn, interval, options = { leading: true, trailing: false }) {

  // leading用来控制第一次输入时否触发函数,trailing用来控制是否在最后一次输入之后再调用函数
  const { leading, trailing } = options
  let lastTime = 0
  let timer = null

  const _throttle = function () {
    const nowTime = new Date().getTime()

    if (!lastTime && leading === false) lastTime = nowTime
    // 用间隔时间减(现在的时间减过去的时间),如果小于0则执行,执行时过去的时间赋值成当前时间
    const remainTime = interval - (nowTime - lastTime)
    if (remainTime <= 0) {
      if (timer) {
        clearTimeout(timer)
        timer = null
      }

      fn()
      lastTime = nowTime
      return
    }

    if (trailing && !timer) {
      timer = setTimeout(() => {
        timer = null
        lastTime = !leading ? 0 : new Date().getTime()
        fn()
      }, remainTime)
    }
  }
  return _throttle
}
节流函数实现03:增加了this绑定、传参、取消的功能
function throttle(fn, interval, options = { leading: true, trailing: false }) {

  // leading用来控制第一次输入时否触发函数,trailing用来控制是否在最后一次输入之后再调用函数
  const { leading, trailing } = options
  let lastTime = 0
  let timer = null

  const _throttle = function (...args) {
    const nowTime = new Date().getTime()

    if (!lastTime && leading === false) lastTime = nowTime
    // 用间隔时间减(现在的时间减过去的时间),如果小于0则执行,执行时过去的时间赋值成当前时间
    const remainTime = interval - (nowTime - lastTime)
    if (remainTime <= 0) {
      if (timer) {
        clearTimeout(timer)
        timer = null
      }
      // 绑定this和参数
      fn.apply(this, args)
      lastTime = nowTime
      return
    }

    if (trailing && !timer) {
      timer = setTimeout(() => {
        timer = null
        lastTime = !leading ? 0 : new Date().getTime()
        fn.apply(this, args)
      }, remainTime)
    }
  }

  _throttle.cancel = function() {
    if(timer) clearTimeout(timer)
    timer = null
    lastTime = 0
  }
  return _throttle
}
节流函数实现04:增加了函数返回值
function throttle(fn, interval, options = { leading: true, trailing: false }) {

  // leading用来控制第一次输入时否触发函数,trailing用来控制是否在最后一次输入之后再调用函数
  const { leading, trailing, resultCallback} = options
  let lastTime = 0
  let timer = null

  const _throttle = function (...args) {
    const nowTime = new Date().getTime()

    if (!lastTime && leading === false) lastTime = nowTime
    // 用间隔时间减(现在的时间减过去的时间),如果小于0则执行,执行时过去的时间赋值成当前时间
    const remainTime = interval - (nowTime - lastTime)
    if (remainTime <= 0) {
      if (timer) {
        clearTimeout(timer)
        timer = null
      }
      // 绑定this和参数
      const result = fn.apply(this, args)
      if(result) resultCallback(result)
      lastTime = nowTime
      return
    }

    if (trailing && !timer) {
      timer = setTimeout(() => {
        timer = null
        lastTime = !leading ? 0 : new Date().getTime()
        const result = fn.apply(this, args)
        if(result) resultCallback(result)
      }, remainTime)
    }
  }

  _throttle.cancel = function() {
    if(timer) clearTimeout(timer)
    timer = null
    lastTime = 0
  }
  return _throttle
}
HTML部分
<!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>Document</title>
</head>
<body>
    <input type="text">
    <button id="cancel">取消</button>

    <script src="./01_节流函数的实现.js"></script>

    <script>
      const inputEl = document.querySelector("input")
      const btn = document.querySelector("#cancel")

      let counter = 0

      const inputChange = function () {
        console.log(`发送了第${++counter}次网络请求`);

        return 11111111
      }
      const throttleChange = throttle(inputChange, 2000, {
        leading: false, 
        trailing: true, 
        resultCallback: function (res) {
          console.log('resultCallback:', res);
        }}
      )

      inputEl.oninput = throttleChange
      btn.onclick = function() {
        throttleChange.cancel()
      }
    </script>
</body>
</html>