防抖和节流

151 阅读2分钟

这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战

之前项目中有一个需求,点击底部提交按钮调用接口只能调用一次,不能多次点击调用否则会频繁触发接口,当时首先想到的就是防抖或是节流,虽然后来发现在这个功能里并不适合用防抖或是节流,但是因为我对这块也不是很了解,所以学习后就在这里记录一下,以便以后查阅。

防抖

概念:当事件被频繁触发时,只在最后一次触发的n秒后调用(即在当前的时间里只调用一次)

使用场景: input 输入搜索

思路:
使用setTimeout方法,每次输入的时候如果时间间隔到了n秒则直接调用ajax方法,否则就clearTiemout,一直等到n秒再调用方法。

 // 防抖
  let setTimeoutFn = null;
  function debounceFn(fn, delay) {
    return () => {
      if (setTimeoutFn) clearTimeout(setTimeoutFn);
        setTimeoutFn = setTimeout(fn, delay);
    }
  }
  const debonceDom = document.getElementById('debonceDom');
  function debounceAjaxFn() {
    const debounceInput = document.getElementById('debounceInput');
    debounceInput.innerHTML = debonceDom.value;
  }

  debonceDom.addEventListener('keyup', debounceFn(debounceAjaxFn, 2000));

image.png
PS:这里我很想弄个动图,可以直观的看到效果,但是我搞了半天还是没弄出来o(╥﹏╥)o,暂时弄个图片凑活看吧☺

节流

概念:当事件被频繁触发时,每隔n秒调用(在频繁触发的时间里可能调用多次)

使用场景:同上

思路: 还是使用setTimeout方法,不过是在方法里面清空延迟以达到每隔n秒调用的效果

  // 节流
  function throttleFn(fn, delay) {
    let times = null; 
    return () => {
      if (!times) {
        times = setTimeout(() => {
          fn.apply(this, arguments);
          times = null; // 在延迟方法里把该方法置空,这也是和防抖的主要区别
        }, delay);
      }
    }
  }

  const throttleDom = document.getElementById('throttleDom');
  function throttleAjaxFn() {
    const throttleInput = document.getElementById('throttleInput');
    throttleInput.innerHTML = throttleDom.value;
  }
  throttleDom.addEventListener('keyup', throttleFn(throttleAjaxFn, 2000));

总结

防抖和节流我觉得都可以在像input输入、鼠标悬浮、滚轮滚动和窗口size更改等状态下使用,就看想要哪种效果啦。

参考资料:
mp.weixin.qq.com/s/Vkshf-nED…
juejin.cn/post/684490…