乐趣区

模拟实现underscore中的防抖debounce

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

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div style="height: 3000px"></div>
</body>
<script src="./debounce.js"></script>
<!-- <script src="https://cdn.jsdelivr.net/npm/underscore@1.10.2/underscore.min.js"></script> -->
<script>

  // 防抖函数
  var debounce = _.debounce(function () {console.log((new Date()))
    console.log('hello debounce')
  }, 1500, true)
  window.onscroll = debounce
  // 第三个参数为 true 立即调用  滑动时立即执行
  // 第三个参数为 false 默认 等待 1500 时间后执行 两次触发间隔大于 1500 才执行
  // 核心在于上一次调用防抖函数与这一次调用之间是否大于间隔 1500 只有大于时才会执行
  // 使用场景:发送 ajax 请求时使用
  // 两次触发间隔大于指定值时调用
</script>
</html>

实现:

// debounce.js
var _ = {}
_.now = Date.now

_.debounce = function (func, wait, immediate) {
  var lastTime, timeOut, args, result
  // 防抖
  var later = function () {var last = _.now() - lastTime
    if (last < wait) {timeOut = setTimeout(later, wait - last)
    } else {
      timeOut = null
      if (!immediate) {result = func.apply(null, args)
      }
    }
  }
  return function () {
    args = arguments
    lastTime = _.now()
    var callNow = immediate && !timeOut
    if (!timeOut) {timeOut = setTimeout(later, wait)
    }
    if (callNow) {result = func.apply(null, args)
    } 
    return result
  }
}
退出移动版