专业-基础

[前端基础]最后一次看:节流&防抖

2021-06-07  本文已影响0人  捡了幸福的猪

节流

const throttle = (fn, wait = 100) => {
  let previous = 0;
  return function(...args) {
    let now = +new Date();
    if (now - previous > wait) {
      previous = now;
      fn.apply(this, args)
    }
  }
}
效果: throttle1.png

分析:绑定在 mousemove 上的事件, 经过 throttle 调用。 此实现方式为开始即触发, 但最后不会触发(看上图的最后部分)

2、原理: 初次调用函数,函数直接执行,执行后设置一个定时器,指定下次执行时机; 下次函数调用,如果发现有定时器,就算了...
实现:

const throttle = (fn, wait = 50) => {
 let timer = null;
 return function(...args) {
  if (timer) return;
    fn.apply(this, args)
    timer = setTimeout(() => {
       timer = null;
       fn.apply(this, args)
   }, wait);
  }
}

效果:


throttle2.png

分析: 绑定在 mousemove 上的事件, 经过 throttle 调用。 此实现方式为开始即触发, 但最后也会触发(看上图的最后部分)

防抖

function debounce(fn, wait = 50) {
  let timer = null

  return function(...args) {
      if (timer) clearTimeout(timer)
      timer = setTimeout(() => {
          fn.apply(this, args)
      }, wait)
  }
}
效果: debounce1.png

分析: 绑定在 mousemove 上的事件, 经过 debounce 调用。 此实现方式为开始不触发, 停止mousemove 后经过指定时间触发(看上图的最后部分)

2、 上面实现方式的效果是 持续触发都不会进行函数调用,只有停止时才调用, 那如果 想开始就立即调用呢?
实现:

function debounce(fn, wait = 50) {
  let timer = null
  return function(...args) {
      if (timer) clearTimeout(timer)
      if (!timer) {
          fn.apply(this, args)
      }
      timer = setTimeout(() => {
          timer= null;
          fn.apply(this, args)
      }, wait)
  }
}

效果:


立即执行的debounce.png

防抖&节流

防抖& 节流效果对比.png

Lodash & underscore

Lodash & underscore 工具库都有对 这两个函数的实现, 其功能更加完善,代码更健壮。 其中包含功能为{leading: boolean; trailing: boolean} , 即 这两个开关分别控制是否需要响应事件刚开始以及最后的那次调用。

参考文档:
1、demo code(文中的测试代码来源)
2、throttle & debounce
3、Lodash

hi 要走了么,点赞了嘛

上一篇 下一篇

猜你喜欢

热点阅读