函数防抖

事件触发n秒后触发的回调函数,如果在这个时间内事件再次被触发,则重新计时。
如果有人进电梯(触发事件),那电梯将在10秒钟后出发(执行事件监听器),这时如果又有人进电梯了(在10秒内再次触发该事件),我们又得等10秒再出发(重新计时)。
给按钮加函数防抖防止表单多次提交,按一下5s后提交,5s内再按一下还是5s后提交。

实现原理

debounce函数就是对事件函数进行包装。
在防抖函数中设置一个计时器,传入的函数如果被触发了,那么计时器就被清除并且重新设置一个计时器。

  1. function debounce(fn, delay) {
  2. var timer = null;
  3. return function () {
  4. let context = this
  5. let args = arguments
  6. if (timer) {
  7. clearTimeout(timer);//清除,但是timer并不是null,还是存在值
  8. timer = null;
  9. }
  10. //为了防止首次触发延迟,如果需要(比如表单验证),那么可以去掉,
  11. 也可以外部传入参数控制
  12. timer = setTimeout(function () {
  13. fn.apply(context, args)
  14. }, delay)
  15. }
  16. }

函数节流

规定一个单位时间,在这个单位时间内,只能有一次触发事件的回调函数执行,如果在同一个单位时间内某事件被触发多次,只有一次能生效。

实现原理

function throttle(fn, time) {
  let last = null;

  return function () {
    let context = this
    let args = arguments
    let now = new Date()
    if (now - last > time || !last) {//间隔的毫秒数,第一次无论事件多短都触发
      fn.apply(context, args);
      last = now
    }
  }
}

let fn = ()=>{
  console.log('成功')
}
function throttle2(fn, time) {
    let timer = null;
    return function () {
        let context = this;
        let args = arguments;
        if (!timer) {
            timer = setTimeout(function () {
                fn.apply(context, args);
                timer = null;
            }, time)
        }
    }
}