防抖和节流

在开发中我们经常会遇见一些频繁触发的事件,比如resize、scroll、mousemove等。那如果这些事件是复杂的回调函数或是数据请求,连续的被触发之后,浏览器反应不过来,就会出现卡顿的现象,为了解决这个问题,就出现了两种解决方案:防抖(debounce)和 节流(throttle)

防抖(debounce)

原理:触发高频事件后n秒内,函数只会执行一次,如果在一个事件触发的n秒内再次触发这个事件,那会以新的触发时间重新计算。总之,就是在触发完事件的n秒内不再触发事件,才会再执行函数。

实现:

function debounce(fn, wait) {

        var timer = null;

        return function () {

            clearTimeout(timer);

            timer = setTimeout(() => {

                fn.apply(this, arguments);

            }, wait);

        }

    }

若想立即执行并在n秒内取消 debounce 函数的做法(immediate参数判断是否是立刻执行)

function debounce(fn, wait, immediate) {

    var timer, result;

    var debounced = function () {

        if (timer) clearTimeout(timer);

        if (immediate) {

            // 如果已经执行过,不再执行

            var callNow = !timeout;

            timer = setTimeout(() => {

                timer = null;

            }, wait);

            if (callNow) result = func.apply(this, arguments)

        }

        else {

            timer = setTimeout(() => {

                fn.apply(this, arguments);

            }, wait);

        }

        return result;

    };

    debounced.cancel = function() {

        clearTimeout(timer);

        timer = null;

    };

    return debounced;

}

节流(throttle)

原理:持续触发事件,每隔一段时间,只执行一次函数。就是说会稀释函数的执行频率。

实现:关于节流的实现,有两种主流的实现方式,一种是使用时间戳,一种是设置定时器。

使用时间戳:

function throttle(fn, wait) {

      var previous = 0;

      return function () {

          var now = +new Date();

          if (now - previous > wait) {

              fn.apply(this, arguments);

              previous = now;

          }

      }

  }

使用定时器:当事件触发时,设置一个定时器,再次触发事件时,如果定时器存在,就不执行,直到执行定时器,执行函数,清空定时器。

function throttle(fn, wait) {

    var timer;

    var previous = 0;

    return function() {

        if (!timer) {

            timer = setTimeout(() => {

                timer = null;

                fn.apply(this, arguments)

            }, wait)

        }

    }

}

比较以上两种方法:

时间戳方法事件会立刻执行,定时器方法事件会在 n 秒后第一次执行;

时间戳方法事件停止触发后没有办法再执行事件,定时器方法事件停止触发后依然会再执行一次事件。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Ps: 比如搜索框,用户在输入的时候使用change事件去调用搜索,如果用户每一次输入都去搜索的话,那得消耗多大的...
    燕自浩阅读 11,163评论 0 1
  • 一、问题 如何解决用户频繁操作所带来的性能问题? 二、场景 简书中的Markdown预览功能,希望用户停止输入0....
    Eric_lwh阅读 2,948评论 0 0
  • 防抖和节流是针对响应跟不上触发频率这类问题的两种解决方案 debounce,去抖动。策略是当事件被触发时,设定一个...
    皇甫圣坤阅读 2,920评论 0 0
  • 需求:最近面试,面试官问说一下你项目中做了哪些优化?小哥哥:不由得想起了,防抖和节流。面试官:能不能手撕一下。老规...
    Nothinglefttosa阅读 2,656评论 0 0
  • 一、什么是防抖和节流 Ps: 比如搜索框,用户在输入的时候使用change事件去调用搜索,如果用户每一次输入都去搜...
    拾柒_aab0阅读 1,950评论 0 1