JavaScript函数节流和函数防抖之间的区别


Posted in Javascript onFebruary 15, 2017

一、概念解释

函数节流和函数防抖,两者都是优化高频率执行js代码的一种手段。

大家大概都知道旧款电视机的工作原理,就是一行行得扫描出色彩到屏幕上,然后组成一张张图片。由于肉眼只能分辨出一定频率的变化,当高频率的扫描,人类是感觉不出来的。反而形成一种视觉效果,就是一张图。就像高速旋转的风扇,你看不到扇叶,只看到了一个圆一样。

同理,可以类推到js代码。在一定时间内,代码执行的次数不一定要非常多。达到一定频率就足够了。因为跑得越多,带来的效果也是一样。倒不如,把js代码的执行次数控制在合理的范围。既能节省浏览器CPU资源,又能让页面浏览更加顺畅,不会因为js的执行而发生卡顿。这就是函数节流和函数防抖要做的事。

函数节流是指一定时间内js方法只跑一次。比如人的眨眼睛,就是一定时间内眨一次。这是函数节流最形象的解释。

函数防抖是指频繁触发的情况下,只有足够的空闲时间,才执行代码一次。比如生活中的坐公交,就是一定时间内,如果有人陆续刷卡上车,司机就不会开车。只有别人没刷卡了,司机才开车。

二、函数节流

函数节流应用的实际场景,多数在监听页面元素滚动事件的时候会用到。因为滚动事件,是一个高频触发的事件。以下是监听页面元素滚动的示例代码:

// 函数节流
var canRun = true;
document.getElementById("throttle").onscroll = function(){
 if(!canRun){
 // 判断是否已空闲,如果在执行中,则直接return
 return;
 }
 canRun = false;
 setTimeout(function(){
 console.log("函数节流");
 canRun = true;
 }, 300);
};

函数节流的要点是,声明一个变量当标志位,记录当前代码是否在执行。

如果空闲,则可以正常触发方法执行。

如果代码正在执行,则取消这次方法执行,直接return。

这个方法的作用是监听ID为throttle元素的滚动事件。

当canRun为true,则代表现在的滚动处理事件是空闲的,可以使用。

通过关卡if(!canRun),等于就拿到了通行证。然后下一步的操作就是立马将关卡关上canRun=false。这样,其他请求执行滚动事件的方法,就被挡回去了。

接着用setTimeout规定最小的时间间隔300,接着再执行setTimeout方法体里面的内容。

最后,等setTimeout里面的方法都执行完毕,才释放关卡canRun=true,允许下一个访问者进来。

这个函数节流的实现形式,需要注意的是执行的间隔时间是>=300ms。如果具体执行的方法是包含callback的,也可以将canRun=true这一步放到callback中。理解了函数节流的关卡设置重点,其实改起来就简单多了。

三、函数防抖

函数防抖的应用场景,最常见的就是用户注册时候的手机号码验证和邮箱验证了。只有等用户输入完毕后,前端才需要检查格式是否正确,如果不正确,再弹出提示语。以下还是以页面元素滚动监听的例子,来进行解析:

// 函数防抖
var timer = false;
document.getElementById("debounce").onscroll = function(){
 clearTimeout(timer); // 清除未执行的代码,重置回初始化状态
 timer = setTimeout(function(){
 console.log("函数防抖");
 }, 300);
};

函数节流的要点,也是需要一个setTimeout来辅助实现。延迟执行需要跑的代码。

如果方法多次触发,则把上次记录的延迟执行代码用clearTimeout清掉,重新开始。

如果计时完毕,没有方法进来访问触发,则执行代码。

这个方法的作用是监听ID为debounce元素的滚动事件

进入滚动事件方法体的时候,做的第一件事就是清除上次未执行的setTimeout。而setTimeout的引用id由变量timer记录。

clearTimeout方法,允许传入无效的值。所以这里直接执行clearTimeout即可。

然后,将需要执行的代码放入setTimeout中,再返回setTimeout引用给timer缓存。

如果倒计时300ms以后,还没有新的方法触发滚动事件,则执行setTimeout中的代码。

函数防抖的实现重点,就是巧用setTimeout做缓存池,而且可以轻易地清除待执行的代码。

其实,用队列的方式也可以做到这种效果。这里就不深入了。

四、在线demo

JavaScript函数节流和函数防抖之间的区别

这是我写的一个测试demo,把鼠标移动到模块上方,滚动滚轮,即可在控制台查看输出效果。

demo地址:https://wall-wxk.github.io/blogDemo/2017/02/15/throttleAndDebounce.html

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持三水点靠木!

Javascript 相关文章推荐
js 解决“options为空或不是对象”
Dec 22 Javascript
单元选择合并变色示例代码
May 26 Javascript
$(document).ready(function() {})不执行初始化脚本
Jun 19 Javascript
js鼠标点击图片实现随机变换图片的方法
Feb 16 Javascript
AngularJS实现标签页的两种方式
Sep 05 Javascript
jQuery过滤选择器用法示例
Sep 12 Javascript
Bootstrap标签页(Tab)插件使用方法
Mar 21 Javascript
[js高手之路]设计模式系列课程-发布者,订阅者重构购物车的实例
Aug 29 Javascript
axios拦截设置和错误处理方法
Mar 05 Javascript
微信小程序移动拖拽视图-movable-view实例详解
Aug 17 Javascript
在vue中利用v-html按分号将文本换行的例子
Nov 14 Javascript
JS数组索引检测中的数据类型问题详解
Jan 11 Javascript
javascript滚轮事件基础实例讲解(37)
Feb 14 #Javascript
基于canvas的二维码邀请函生成插件
Feb 14 #Javascript
javascript事件的绑定基础实例讲解(34)
Feb 14 #Javascript
javascript深拷贝和浅拷贝详解
Feb 14 #Javascript
javascript事件的传播基础实例讲解(35)
Feb 14 #Javascript
微信小程序中实现一对多发消息详解及实例代码
Feb 14 #Javascript
有关JS中的0,null,undefined,[],{},'''''''',false之间的关系
Feb 14 #Javascript
You might like
php对文件进行hash运算的方法
2015/04/03 PHP
PHP实现链式操作的核心思想
2015/06/23 PHP
thinkphp下MySQL数据库读写分离代码剖析
2017/04/18 PHP
JQuery 弹出框定位实现方法
2010/12/02 Javascript
jquery调用wcf并展示出数据的方法
2011/07/07 Javascript
JS常用字符串处理方法应用总结
2014/05/22 Javascript
JS简单模拟触发按钮点击功能的方法
2015/11/30 Javascript
JS 对象(Object)和字符串(String)互转方法
2016/05/20 Javascript
微信小程序 详解Page中data数据操作和函数调用
2017/01/12 Javascript
JS 设置Cookie 有效期 检测cookie
2017/06/15 Javascript
React-native桥接Android原生开发详解
2018/01/17 Javascript
js监听html页面的上下滚动事件方法
2018/09/11 Javascript
jQuery实现的记住帐号密码功能完整示例
2019/08/03 jQuery
详解JavaScript自定义函数
2020/07/29 Javascript
Python3中多线程编程的队列运作示例
2015/04/16 Python
python使用Tkinter显示网络图片的方法
2015/04/24 Python
Python文件右键找不到IDLE打开项解决办法
2015/06/08 Python
Python实现将MySQL数据库表中的数据导出生成csv格式文件的方法
2018/01/11 Python
利用python将图片版PDF转文字版PDF
2019/05/03 Python
numpy.random模块用法总结
2019/05/27 Python
解决Python3 控制台输出InsecureRequestWarning问题
2019/07/15 Python
Win10 安装PyCharm2019.1.1(图文教程)
2019/09/29 Python
Python实现点云投影到平面显示
2020/01/18 Python
基于Tensorflow高阶读写教程
2020/02/10 Python
python使用正则表达式去除中文文本多余空格,保留英文之间空格方法详解
2020/02/11 Python
CSS3 text shadow字体阴影效果
2016/01/08 HTML / CSS
web页面录屏实现
2019/02/12 HTML / CSS
GANT英国官方网上商店:甘特衬衫
2018/02/06 全球购物
如何启动时不需输入用户名与密码
2014/05/09 面试题
大学生职业生涯规划书模板
2014/01/03 职场文书
车祸赔偿收入证明
2014/01/09 职场文书
家长通知书教师评语
2014/04/17 职场文书
优秀党员学习焦裕禄精神思想汇报范文
2014/09/10 职场文书
2015年机关党建工作总结
2015/05/22 职场文书
家长反馈意见及建议
2015/06/03 职场文书
Django 实现jwt认证的示例
2021/04/30 Python