前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >‘underscore系列之throttle“‘

‘underscore系列之throttle“‘

作者头像
用户9298250
发布2022-01-10 13:42:29
3620
发布2022-01-10 13:42:29
举报

underscore函数节流

前言

在说underscore函数节流之前, 还是明确概念, 什么是函数节流。函数节流简单来说就是'开源节流', 什么意思呢?就是减少某个函数调用的太频繁, 降低频次。一般来讲, 对于dom的频繁操作会引起浏览器的重绘或者重排, 这个时候我们就可以来使用节流不要让他过快的操作dom, 从而页面渲染起来也会更加流畅。 举个场景: dom元素的移动与拖拽, 我默认都做过这个功能。对于dom元素的频繁拖拽, 对于一些性能不太好的浏览器(说的就是你IE)会有很大的损耗, 这个时候我们就可以适当的去降低这个事件的调用频次。 当然调用的频次也要有一个合适的阈值。不然也会引出意外的问题。。。

underscore函数throttle

上面提到了函数调用频次, 这个频次也就是调用时间, 所以在underscore中关于throttle函数是基于定时器与时间差来调用函数运行的频次。还有就是throttle函数接收三个参数, 关于最后一个参数我到最后再讲。 我们看下源码:

代码语言:javascript
复制
var now = Date.now || function() {
  return new Date().getTime();
};
var throttle = function(func, wait, options) {
  var timeout, context, args, result;
  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;
  };
  var throttled = function() {
    var now = this.now();
    if (!previous && options.leading === false) previous = now;
    // console.log(previous)
    var remaining = wait - (now - previous);
    // console.log(remaining);
    // console.log(remaining)
    context = this;
    args = arguments;
    //  remaining > wait 表示客户端系统时间被调整过
    if (remaining <= 0 || remaining > wait) {
      if (timeout) {
        clearTimeout(timeout);
        timeout = null;
        //  timeout = null设置为null,不仅仅是为了防止内存泄漏,而是clearTimeout(timeout)后,timeout的值并不会清空,如果不设置为null,就不能根据!timeout设置下次的timeout
      }
      previous = now;
      result = func.apply(context, args);
      // console.log(result)
      if (!timeout) context = args = null;  //  这里不太明白, timeout 不是已经赋值为null了吗
      //  context = args = null; 引用值为空, 防止内存泄露。
    } else if (!timeout && options.trailing !== false) {
      // console.log(remaining);
      timeout = setTimeout(later, remaining);
      // console.log(later, remaining)
    }
    return result;
  };

  throttled.cancel = function() {
    clearTimeout(timeout);
    previous = 0;
    timeout = context = args = null;
  };

  return throttled;
};
  var func = function () {
  console.log('wangdaye')
}
window.onscroll = throttle(func, 1000);

我从自己的角度分析下: 首先滚动进入throttle函数携带两个参数, 函数内定义变量先不管, 直接说throttled函数, 首先要获取当前时间, 然后就是计算时间差, 当然第一次调用我们肯定是不希望要延迟加载, 所以变量remaining一定是负值, 获取最新时间戳, 然后调用函数。当连续调用时, 变量remaining是一个正值, 然后定时器延迟调用later方法, 刷新时间戳, timeout为null。当等待一秒钟再次调用时remaining为负值, 且已经存在timeout, 所以清空上一次定时器, timeout并为null。

我再说说关于第三个参数, 第三个参数有两种调用方式, 第一种是, {leading: false}, 当传递的方式的为{leading: false}就会忽略scroll开始前的回调。第二种方式是, {trailing: false}, 当传递方式为{trailing: false}时, scroll结束时会被忽略。

最后我还是希望可以debugger或者console.log下, 自己多去理解下, 我相信就会更加明白关于函数节流的知识点。 就到这了。。。。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/12/24 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • underscore函数节流
    • 前言
    • underscore函数throttle
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档