专栏首页大数据钻研谈谈JS中的函数节流

谈谈JS中的函数节流

好吧,一直在秋招中,都没怎么写博客了。。。今天赶紧来补一补才行。。。我发现,在面试中,讲到函数节流好像可以加分,尽管这并不是特别高深的技术,下面就聊聊吧! ^_^

备注:以下内容部分来自《JavaScript高级程序设计》

函数节流的目的

从字面上就可以理解,函数节流就是用来节流函数从而一定程度上优化性能的。例如,DOM 操作比起非DOM 交互需要更多的内存和CPU时间。连续尝试进行过多的DOM 相关操作可能会导致浏览器挂起,有时候甚至会崩溃。尤其在IE 中使用onresize 事件处理程序的时候容易发生,当调整浏览器大小的时候,该事件会连续触发。在onresize 事件处理程序内部如果尝试进行DOM 操作,其高频率的更改可能会让浏览器崩溃。又例如,我们常见的一个搜索的功能,我们一般是绑定keyup事件,每按下一次键盘就搜索一次。但是我们的目的主要是每输入一些内容搜索一次而已。为了解决这些问题,就可以使用定时器对函数进行节流。

函数节流的原理

某些代码不可以在没有间断的情况连续重复执行。第一次调用函数,创建一个定时器,在指定的时间间隔之后运行代码。当第二次调用该函数时,它会清除前一次的定时器并设置另一个。如果前一个定时器已经执行过了,这个操作就没有任何意义。然而,如果前一个定时器尚未执行,其实就是将其替换为一个新的定时器。目的是只有在执行函数的请求停止了一段时间之后才执行。

函数节流的基本模式

JavaScript

var processor = {

   timeoutId: null,

     //实际进行处理的方法

   performProcessing: function(){

     //实际执行的代码

   },

  //初始处理调用的方法

  process: function(){

    clearTimeout(this.timeoutId);

    var that = this;

    this.timeoutId = setTimeout(function(){

      that.performProcessing();

    }, 100);

  }

};

//尝试开始执行

processor.process();

好吧,看得确实有点迷糊。下面通过一个例子来详细说明,并且在这个基础模式之上做一个优化处理。

例子场景:实现常见的搜索功能

①没有使用函数节流的情况下,为input绑定keyup事件处理函数,在控制台输出我输入的内容。

测试主要代码:

XHTML

1

<input id="search" type="text" name="search">

JavaScript

function queryData(text){

    console.log("搜索:" + text);

  }

var input = document.getElementById("search");

  input.addEventListener("keyup", function(event){ queryData(this.value);

});

结果如图:

可以看出,这种情况下,每按下一个键盘键,就输出了一次。短短的一些内容,输出了14次,如果每一次都是一次ajax查询请求的话就发了14个请求了。在性能上的消耗可想而知。

②使用基本的函数节流模式的情况。

测试主要代码:

XHTML

1

<input id="search" type="text" name="search">

JavaScript

function queryData(text){

  console.log("搜索:" + text);

}

var input = document.getElementById("search");

input.addEventListener("keyup", function(event){

  throttle(queryData, null, 500, this.value);

  // queryData(this.value);

});

function throttle(fn,context,delay,text){

  clearTimeout(fn.timeoutId);

  fn.timeoutId = setTimeout(function(){

  fn.call(context,text);

  },delay);

}

结果如图:

可以看出,这种情况下,输入了好一些内容,只输出了一次,因为测试的时候设置了两次输入间隔是500ms,实际应用可根据情况设置。显然,这在性能上大大滴得到了优化。不过,这样的话,有一个新问题,如下图:

好吧,或许看不出端倪。其实问题就是,假如我不断地输入,输入了很多内容,但是我每两次之间的输入间隔都小于自己设置的delay值,那么,这个queryData搜索函数就一直得不到调用。实际上,我们更希望的是,当达到某个时间值时,一定要执行一次这个搜索函数。所以,就有了函数节流的改进模式。

③函数节流增强版

测试的主要代码:

XHTML

1

<input id="search" type="text" name="search">

JavaScript

function queryData(text){

  console.log("搜索:" + text);

}

var input = document.getElementById("search");

input.addEventListener("keyup", function(event){

  throttle(queryData, null, 500, this.value,1000);

  // throttle(queryData, null, 500, this.value);

  // queryData(this.value);

});

        

function throttle(fn,context,delay,text,mustApplyTime){

  clearTimeout(fn.timer);

  fn._cur=Date.now();  //记录当前时间

 

  if(!fn._start){      //若该函数是第一次调用,则直接设置_start,即开始时间,为_cur,即此刻的时间

    fn._start=fn._cur;

  }

  if(fn._cur-fn._start>mustApplyTime){ <br>            //当前时间与上一次函数被执行的时间作差,与mustApplyTime比较,若大于,则必须执行一次函数,若小于,则重新设置计时器

     fn.call(context,text);

     fn._start=fn._cur;

  }else{

    fn.timer=setTimeout(function(){

    fn.call(context,text);

    },deley);

  }

}

测试结果如图:

显然,连续的输入,到一定时间间隔之后,queryData函数必然会被调用,但是又不是频繁的调用。这既达到了节流的目的,又不会影响用户体验。

④进一步的优化

进一步的话,就是可以在调用throttle函数之前,先对输入的内容进行判断,若其值为空、值不变都不用再调用。这里就不详说了

本文分享自微信公众号 - 大数据钻研(bigdata118)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2016-11-13

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 十年Web开发技术经验感受

    这里列举的后台技术,所有是我工作中所有的要点,并进行了简单的归类,如果你有更好的归类方式,欢迎提出。   我想其中的重点应该还是服务器脚本部分,例如Java,...

    用户1667431
  • 成为web开发高手的学习之路是如何炼成的!

    如果你已经是一名优秀的Web开发人员,那请路过即可。如果你还是一个准备入行或刚入行的菜鸟,那本文倒值得一读。要成为一名优秀的Web开发人员,没有捷径可走,...

    用户1667431
  • DIV+CSS初学者需重视的10个简单问题与技巧

    DIVCSS初学者往往感觉自己遇到很多莫明其妙的问题,其实只是一些小细节没有引起重视,下面罗列了10个问题与技巧,温故而知新。 一、检查HTML元素是否有拼写错...

    用户1667431
  • 项目列表dl、dt、dd使用

    小蔚
  • 【学习】教程:产品运营分析之Excel实用入门

    为什么写Excel,因为昨天给实习产品经理布置了一道题目,对20多万条搜索关键词进行文本分析,半天时间,两位新同学分析完毕,晚上23点给我发的邮件。我也对这20...

    小莹莹
  • jQuery on()方法

    以上三种方法在jQuery1.8之后都不推荐使用,官方在1.9时已经取消使用live()方法了,所以建议都使用on()方法。

    山河木马
  • 当机器都会“学习”了,你还想不学习么? | 数据科学50人· 谢梁

    如今,我们每个人都在谈论“数据科学”,《哈佛商业评论》杂志甚至将数据科学家定义为“21世纪最性感的职业”。在这个大数据时代,究竟什么是数据科学?数据科学家又究竟...

    DT数据侠
  • JQuery各种点击事件的区别

    在工作中,经常用到js的点击事件,有好多种表现形式,今天抽空总结一下它们的区别与联系。废话不多说,开始写测试案例。首先声明,本人水平有限,如果有错误之处,还请指...

    用户6182664
  • Javascript模块化编程(一)

    随着网站逐渐变成"互联网应用程序",嵌入网页的Javascript代码越来越庞大,越来越复杂。 网页越来越像桌面程序,需要一个团队分工协作、进度管理、单元测...

    汤高
  • Javascript模块化编程(一):模块的写法

    随着网站逐渐变成"互联网应用程序",嵌入网页的Javascript代码越来越庞大,越来越复杂。 ? 网页越来越像桌面程序,需要一个团队分工协作、进度管理、单元测...

    ruanyf

扫码关注云+社区

领取腾讯云代金券