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

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

函数节流的目的

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

函数节流的原理

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

函数节流的基本模式

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事件处理函数,在控制台输出我输入的内容。

测试主要代码:

HTMl:
<input id="search" type="text" name="search">
JS:
<script>
function queryData(text){
console.log("搜索:" + text);
}
var input = document.getElementById("search");
input.addEventListener("keyup", function(event){ queryData(this.value);
});
</script>

结果如图:

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

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

测试主要代码:

HTML:
<input id="search" type="text" name="search">
JS:
<script>
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);
}
</script>

结果如图:

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

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

③函数节流增强版

测试的主要代码:

HTML:
<input id="search" type="text" name="search">
JS:
<script>
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){
//当前时间与上一次函数被执行的时间作差,与mustApplyTime比较,若大于,则必须执行一次函数,若小于,则重新设置计时器
fn.call(context,text);
fn._start=fn._cur;
}else{
fn.timer=setTimeout(function(){
fn.call(context,text);
},delay);
}
}
</script>

测试结果如图:

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

④进一步的优化

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

更多学习链接

详细改进实例

节流与去抖

好吧,就到这了,如果有错误的地方,还要指正哦...^_^

谈谈JS中的函数节流的更多相关文章

  1. [转] 谈谈JS中的函数节流

    函数节流的目的 从字面上就可以理解,函数节流就是用来节流函数从而一定程度上优化性能的.例如,DOM 操作比起非DOM 交互需要更多的内存和CPU 时间.连续尝试进行过多的DOM 相关操作可能会导致浏览 ...

  2. JS中的函数节流throttle详解和优化

    JS中的函数节流throttle详解和优化在前端开发中,有时会为页面绑定resize事件,或者为一个页面元素绑定拖拽事件(mousemove),这种事件有一个特点,在一个正常的操作中,有可能在一个短的 ...

  3. 【javascript】js中的函数节流和函数防抖

    一.概念解释  函数节流和函数防抖,两者都是优化高频率执行js代码的一种手段.  大家大概都知道旧款电视机的工作原理,就是一行行得扫描出色彩到屏幕上,然后组成一张张图片.由于肉眼只能分辨出一定频率的变 ...

  4. JS中的函数节流

    函数节流的目的 从字面上就可以理解,函数节流就是用来节流函数从而一定程度上优化性能的.例如,DOM 操作比起非DOM 交互需要更多的内存和CPU时间.连续尝试进行过多的DOM 相关操作可能会导致浏览器 ...

  5. 谈谈JS中的高级函数

    博客原文地址:Claiyre的个人博客如需转载,请在文章开头注明原文地址 在JavaScript中,函数的功能十分强大.它们是第一类对象,也可以作为另一个对象的方法,还可以作为参数传入另一个函数,不仅 ...

  6. JS中的函数,Array对象,for-in语句,with语句,自定义对象,Prototype

    一)函数 A)JS中的函数的定义格式: function add(a,b) { var sum = a+b; document.write("两个数的和是:" + sum); // ...

  7. js中的函数,Date对象,Math对象和数组对象

    函数就是完成某个功能的一组语句,js中的函数由关键字 function + 函数名 + 一组参数定义;函数在定义后可以被重复调用,通常将常用的功能写成一个函数,利用函数可以使代码的组织结构更多清晰. ...

  8. js中getByClass()函数

    js中getByClass()函数进化史 对于js来说,我想每一个刚接触它的人都应该会抱怨:为什么没有一个通过class来获取元素的方法.尽管现在高版本的浏览器已经支持getElementsByCla ...

  9. JS中的函数、Bom、DOM及JS事件

    本期博主给大家带来JS的函数.Bom.DOM操作,以及JS各种常用的数据类型的相关知识,同时,这也是JavaScript极其重要的部分,博主将详细介绍各种属性的用法和方法. 一.JS中的函数 [函数的 ...

随机推荐

  1. 【.net 深呼吸】细说CodeDom(4):类型定义

    上一篇文章中说了命名空间,你猜猜接下来该说啥.是了,命名空间下面就是类型,知道了如何生成命名空间的定义代码,之后就该学会如何声明类型了. CLR的类型通常有这么几种:类.接口.结构.枚举.委托.是这么 ...

  2. Kali对wifi的破解记录

    好记性不如烂笔头,记录一下. 我是在淘宝买的拓实N87,Kali可以识别,还行. 操作系统:Kali 开始吧. 查看一下网卡的接口.命令如下 airmon-ng 可以看出接口名称是wlan0mon. ...

  3. 使用 Roslyn 编译器服务

    .NET Core和 .NET 4.6中 的C# 6/7 中的编译器Roslyn 一个重要的特性就是"Compiler as a Service",简单的讲,就是就是将编译器开放为 ...

  4. Java 征途:行者的地图

    前段时间应因缘梳理了下自己的 Java 知识体系, 成文一篇望能帮到即将走进或正在 Java 世界跋涉的程序员们. 第一张,基础图 大约在 2003 年我开始知道 Java 的(当时还在用 Delph ...

  5. Docker笔记一:基于Docker容器构建并运行 nginx + php + mysql ( mariadb ) 服务环境

    首先为什么要自己编写Dockerfile来构建 nginx.php.mariadb这三个镜像呢?一是希望更深入了解Dockerfile的使用,也就能初步了解docker镜像是如何被构建的:二是希望将来 ...

  6. 来吧,HTML5之基础标签(下)

    <dialog> 标签 定义对话框或窗口. <dialog> 标签是 HTML 5 的新标签.目前只有 Chrome 和 Safari 6 支持 <dialog>  ...

  7. [原] KVM 虚拟化原理探究(2)— QEMU启动过程

    KVM 虚拟化原理探究- QEMU启动过程 标签(空格分隔): KVM [TOC] 虚拟机启动过程 第一步,获取到kvm句柄 kvmfd = open("/dev/kvm", O_ ...

  8. 免费公开课,讲解强大的文档集成组件Aspose,现在可报名

    课程①:Aspose.Total公开课内容:讲解全能型文档管理工具Aspose.Total主要功能及应用领域时间:2016-11-24 14:30 (暂定)报名地址:http://training.e ...

  9. 使用Nginx反向代理 让IIS和Tomcat等多个站点一起飞

    使用Nginx 让IIS和Tomcat等多个站点一起飞 前言: 养成一个好习惯,解决一个什么问题之后就记下来,毕竟“好记性不如烂笔头”. 这样也能帮助更多的人 不是吗? 最近闲着没事儿瞎搞,自己在写一 ...

  10. Firebug中调试中的js脚本中中文内容显示为乱码

    Firebug中调试中的js脚本中中文内容显示为乱码 设置 页面 UFT-8 编码没用, 解决方法:点击 "Firebug"工具栏 中的"选项"---" ...