最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 从underscore库中学习throttle 节流

    正文概述 掘金(阿银)   2021-08-25   513

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

    前言

    前文讲到两种实现版本的节流,这里的高配版本主要将把这两种版本进行优势互补,合并成一个节流函数,通过传参控制具体是要第一时间执行、或者最后一次执行,又或者两者兼得这三种情况

    高配节流实现分析

    使用时间戳可以让节流函数立即执行,使用setTimeout可以让节流函数延迟执行,通过变量控制即可以达到以上需求

    通过高配版的节流 ,达到配置以下三种情况:

    • 第一次执行,末尾不执行
    • 第一次不执行,末尾执行
    • 第一次执行,末尾执行

    代码实现

    <style>
        div {
            background-color: #666;
            height: 300px;
        }
    </style>
    ​
    <div></div>
    ​
    <script>
        let dom = document.getElementsByTagName("div")[0];
        dom.onmousemove = throttle(listenMoveOn, 200);
        
        function listenMoveOn() {
            // 监听的回调做一些事情 
        }
        
        /**
         *
         * @param {function} fn - 回调函数
         * @param {number} wait - 等待时间
         * @param {obejct} options - 配置三种情况
         *   options = {leading: true, trailing: false}; leading 控制第一次是否执行; trailing 控制最后一次是否执行
         */
        function throttle(fn, wait, options) {
           /**
            *
            * @param timer - 定时器
            * @param now - 当前时间
            * @param context - 保存上下文使用
            * @param args - 保存事件参数使用
            */
            let timer, now, context, args;
            old = 0
            
            // 设置默认情况(第一次执行,最后一次不执行)
            if (!options) options = {leading: true, trailing: false} 
    ​
            const later = () => {
                // 这里重置old 是为了避免leading、trailing同时为true与时间戳那边相互影响,这一步相当于清除了时间戳那边的操作
                old = now
                
                clearTimeout(timer)
                timer = null
                fn.apply(context, args)
            }
    ​
            return function () {
                // 同防抖一样,需要闭包保存相关变量
                now = +new Date()
                context = this
                args = arguments
                
                // 配置 leading 走时间戳管理节流
                if (options.leading && now - old > wait) {
                    // 这里重置定时器 是为了避免leading、trailing同时为true时与定时器那边相互影响,这一步相当于清除了定时器那边的操作
                    if (timer) {
                        clearTimeout(timer)
                        timer = null
                    }
                    
                    old = now
                    fn.apply(context, args)
                } 
                // 配置 trailing 走定时器管理节流
                if (options.trailing && !timer) {
                    timer = setTimeout(later, wait)
                }
            }
    ​
        }
    </script>
    

    undercore中的throttle

    最后还是欣赏一下undercore中的throttle源码

      // Returns a function, that, when invoked, will only be triggered at most once
      // during a given window of time. Normally, the throttled function will run
      // as much as it can, without ever going more than once per `wait` duration;
      // but if you'd like to disable the execution on the leading edge, pass
      // `{leading: false}`. To disable execution on the trailing edge, ditto.
      _.throttle = function (func, wait, options) {
        var context, args, result;
        var timeout = null;
        var previous = 0;
        if (!options) options = {};
          
        var later = function () {
          // 定时器方式
          previous = options.leading === false ? 0 : _.now();
          timeout = null;
          result = func.apply(context, args);
          if (!timeout) context = args = null;
        };
        return function () {
          var now = _.now();
          if (!previous && options.leading === false) previous = now;
          var remaining = wait - (now - previous);
          context = this;
          args = arguments;
          // 时间戳方式
          if (remaining <= 0 || remaining > wait) {
            if (timeout) {
              clearTimeout(timeout);
              timeout = null;
            }
            previous = now;
            result = func.apply(context, args);
            if (!timeout) context = args = null;
          } else if (!timeout && options.trailing !== false) {
            timeout = setTimeout(later, remaining);
          }
          return result;
        };
      };
    

    总结

    防抖节流已经全部讲完,通过深入学习也算有所收获啦,以前只知道调用没详细了解原理,这回彻底搞懂了 ? 爱了爱了


    起源地下载网 » 从underscore库中学习throttle 节流

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元