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 相关文章推荐
动态改变textbox的宽高的js
Oct 26 Javascript
escape、encodeURI、encodeURIComponent等方法的区别比较
Dec 27 Javascript
再谈javascript面向对象编程
Mar 18 Javascript
Jquery中LigerUi的弹出编辑框(实现方法)
Jul 09 Javascript
jquery实现先淡出再折叠收起的动画效果
Aug 07 Javascript
JS+html5制作简单音乐播放器
Sep 13 Javascript
详解Vue微信公众号开发踩坑全记录
Aug 21 Javascript
利用express启动一个server服务的方法
Sep 17 Javascript
vue.js 使用axios实现下载功能的示例
Mar 05 Javascript
JS实现左边列表移到到右边列表功能
Mar 28 Javascript
详解Vuex下Store的模块化拆分实践
Jul 31 Javascript
解决LayUI加上form.render()下拉框和单选以及复选框不出来的问题
Sep 27 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语言流程控制中的主动与被动
2012/11/05 PHP
php把session写入数据库示例
2014/02/26 PHP
php实现的简单美国商品税计算函数
2015/07/13 PHP
详细解读PHP的Yii框架中登陆功能的实现
2015/08/21 PHP
使用phpstorm和xdebug实现远程调试的方法
2015/12/29 PHP
详解PHP文件的自动加载(autoloading)
2018/02/04 PHP
PHP实现文字写入图片功能
2019/02/18 PHP
JS event使用方法详解
2008/04/28 Javascript
JavaScript国旗变换效果代码
2008/08/13 Javascript
初学JavaScript第二章
2008/09/30 Javascript
javascript 复杂的嵌套环境中输出单引号和双引号
2009/05/26 Javascript
jquery如何改变html标签的样式(两种实现方法)
2013/01/16 Javascript
如何用angularjs制作一个完整的表格
2016/01/21 Javascript
Node.js 8 中的 util.promisify的详解
2017/06/12 Javascript
浅谈JS获取元素的N种方法及其动静态讨论
2017/08/25 Javascript
使用vue与jquery实时监听用户输入状态的操作代码
2017/09/19 jQuery
jQuery中的类名选择器(.class)用法简单示例
2018/05/14 jQuery
JavaScript使用prototype原型实现的封装继承多态示例
2018/08/31 Javascript
基于layui轮播图满屏是高度自适应的解决方法
2019/09/16 Javascript
[55:56]NB vs Infamous 2019国际邀请赛淘汰赛 败者组 BO3 第二场 8.22
2019/09/05 DOTA
python代码 if not x: 和 if x is not None: 和 if not x is None:使用介绍
2016/09/21 Python
django开发之settings.py中变量的全局引用详解
2017/03/29 Python
PyQt实现界面翻转切换效果
2018/04/20 Python
python numpy之np.random的随机数函数使用介绍
2019/10/06 Python
基于python的列表list和集合set操作
2019/11/24 Python
Python PyQt5运行程序把输出信息展示到GUI图形界面上
2020/04/27 Python
详解Pymongo常用查询方法总结
2021/01/29 Python
HTML5 WebSocket实现点对点聊天的示例代码
2018/01/31 HTML / CSS
美国波道夫·古德曼百货官网:Bergdorf Goodman
2017/11/07 全球购物
民主评议政风行风整改方案
2014/09/17 职场文书
2014年乡镇安全生产工作总结
2014/12/02 职场文书
大学生求职自荐信
2015/03/24 职场文书
大学考试作弊检讨书
2015/05/06 职场文书
小鞋子观后感
2015/06/05 职场文书
JS前端使用canvas实现扩展物体类和事件派发
2022/08/05 Javascript
CSS 鼠标选中文字后改变背景色的实现代码
2023/05/21 HTML / CSS