防抖、节流的小小理解

128 阅读2分钟

1、防抖

在指定的时间内,触发的n次事件或者操作,最终只会执行一次

常用场景:

1)输入框,输入文字后进行接口搜索(比较常用的场景)

2)业务按钮事件,如提交表单等,用户多次点击同一个按钮,在规定时间内多次点击的事件只执行一次

来个简单的demo

    function func(a) {
      console.log(a);
    }
    let f1000 = debounce(func, 1000);
    f1000(1);
    f1000(2);
    f1000(3);
    f1000(4);
    f1000(5);

现在来实现防抖这个函数的代码

    const debounce = (func, ms) => {
      let timeout;
      return function() {
        clearTimeout(timeout);
        timeout = setTimeout(() => {
          func.apply(this, arguments)
        }, ms) 
      }
    }

这样就可以实现在1000ms内执行的5次事件,最终只会输出一次

image.png

理解防抖的思想就可以了

2、节流 (顾名思义就是控制流的多少)--- 节流的场景一般是用于控制某事件在规定时间内只执行一次的操作,在业务开发中,测试人员就很喜欢对着一个按钮疯狂的点击点击,这时候就可以使用节流,在1s内触发的点击事件,只执行一次

节流真的是很绕,多看几次就懂了, 还是用这个例子

    function func(a) {
      console.log(a);
    }
    let f1000 = throttle(func, 1000);
    f1000(1);
    f1000(1);
    f1000(1);
    f1000(1);
    f1000(1);

现在来实现节流throttle这个函数的代码(看不懂的时候,可以在第二步和第三步打印一下saveArgs的值)

const throttle = (func, ms) => {
  let isThrottle = false;
  let saveArgs;
  let saveThis;
  function wrapper () {
    // 第二步
    if (isThrottle) {
      saveArgs = arguments;
      saveThis = this;
      return;
    }
    // 第一步
    func.apply(this, arguments);
    isThrottle = true;
    // 第三步

    setTimeout(() => {
      isThrottle = false;
      if (saveArgs) {
        wrapper.apply(saveThis, saveArgs)
        saveArgs = saveThis = null
      }
    }, ms)
  }
  return wrapper
}

image.png

这里的代码执行完后,为输出2个1,那这里是不是就是不符合我们的预期,我们只想在1s内执行一次

demo的代码只是做了对比,因为上面的第一步,第一次进来的时候就会执行

在这只需要把第一步的 func.apply(this, arguments);去掉,把wrapper.apply(saveThis, saveArgs) 换成func.apply(saveThis, saveArgs) 即可

  • debounce 会在“冷却(cooldown)”期后运行函数一次。适用于处理最终结果。
  • throttle 运行函数的频率不会大于所给定的时间 ms 毫秒。适用于不应该经常进行的定期更新。

目前业务开发中大部分可以使用第三方lodash的库,直接调用api,轮子不用自己造,但还是要懂啊!😭

大佬看了勿喷,也许理解的不够到位,错了才能不断进步的😁

每天学习一点javascript小知识

本文参考来源于: zh.javascript.info/call-apply-…