节流和防抖 区别和实现

节流

实现:

/**
 * 函数节流:开始会执行一次,持续触发事件的话,每隔wait时间执行一次;
 * 应用场景mousemove, scroll等会连续执行的事件,比较适合应用于动画相关的场景。
 * @param fn 需要节流的函数
 * @param wait 间隔时间
 */
export function throttle(fn, wait = 1000) {
    let lastTime = 0; //上次执行的时间
    return function (...args) {
        let now = +new Date();
        if (now - lastTime > wait) {
            lastTime = now;
            fn.apply(this, args);
        }
    }
}

使用:

  mounted() {
    // 触发resize的时候会先执行一次,如果下次触发resize和上次触发resize时间大于wait(不论中间有没有持续触发resize),那么会再次执行函数
    window.addEventListener(
      "resize",
      (this._resize = throttle(()=>{console.log("视口改变")}, 5000))
    );
  },
  destroyed() {
    window.removeEventListener("resize", this._resize);
  }

防抖

实现:

/**
 * 函数防抖:触发事件的wait 时间后才执行; 如果wait 时间内事件持续被触发,则以新触发的时间为标准,然后wait 时间后再执行;
(不持续触发,wait 时间后执行一次;如果持续触发,以最后触发为准,也wait 时间后只执行一次)
 * 应用场景: 输入验证,提交按钮点击事件
 * @param fn 需要防抖的函数
 * @param wait 等待时间
 */

function debounce(fn, wait = 1000) {
    let timer = undefined; //定时器id
    return function (...args) {
        if (timer) clearTimeout(timer);
        timer = setTimeout(() => {
            fn.apply(this, args);
        }, wait);
    }
}

说明

以上持续触发是指wait时间内触发两次以上:
不持续触发时(wait时间内只触发一次): 节流只在触发时执行一次;防抖会在触发事件wait时间后执行一次;
持续触发(wait时间内触发两次以上): 节流在每一个wait时间开始都会执行一次;防抖会在最后一次触发的wait时间后只执行一次

节流和防抖解释起来比较混乱,要自己多去使用,并结合实现的代码,才慢慢会有所体会。

这里推荐一篇司徒正美的节流和防抖文章

posted @ 2019-11-14 14:41  ฅ˙-˙ฅ  阅读(209)  评论(0编辑  收藏  举报