JS函数节流和函数防抖问题分析


Posted in Javascript onDecember 18, 2017

问题1:如果实现了dom拖拽功能,但是在绑定拖拽事件的时候发现每当元素稍微移动一点便触发了大量的回调函数,导致浏览器直接卡死,这个时候怎么办?

JS函数节流和函数防抖问题分析 

**问题2:**如果给一个按钮绑定了表单提交的post事件,但是用户有些时候在网络情况极差的情况下多次点击按钮造成表单重复提交,如何防止多次提交的发生?

为了应对如上场景,便出现了 函数防抖 和 函数节流 两个概念,总的来说:

这两个方法是在 时间轴上控制函数的执行次数。

函数防抖(debounce)

概念: 在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。

生活中的实例: 如果有人进电梯(触发事件),那电梯将在10秒钟后出发(执行事件监听器),这时如果又有人进电梯了(在10秒内再次触发该事件),我们又得等10秒再出发(重新计时)。

函数节流(throttle)

概念: 规定一个单位时间,在这个单位时间内,只能有一次触发事件的回调函数执行,如果在同一个单位时间内某事件被触发多次,只有一次能生效。

生活中的实例: 我们知道目前的一种说法是当 1 秒内连续播放 24 张以上的图片时,在人眼的视觉中就会形成一个连贯的动画,所以在电影的播放(以前是,现在不知道)中基本是以每秒 24 张的速度播放的,为什么不 100 张或更多是因为 24 张就可以满足人类视觉需求的时候,100 张就会显得很浪费资源。

分析图

假设,我们观察的总时间为10秒钟,规定1秒作为一次事件的最小间隔时间。

如果触发事件的频率是 0.5s/次 ,那么函数防抖如图

JS函数节流和函数防抖问题分析 

因为始终没法等一秒钟就被再次触发了,所以最终没有一次事件是成功的。

函数节流如图

JS函数节流和函数防抖问题分析 

因为控制了最多一秒一次,频率为 0.5s/次 ,所以每一秒钟就有一次事件作废。最终控制成 1s/次

如果触发事件的频率是 2s/次 ,那么

函数防抖如图

JS函数节流和函数防抖问题分析 

因为 2s/次
已经大于了规定的最小时间,所以每计时两秒便触发一次。

函数节流如图

JS函数节流和函数防抖问题分析 

同样, 2s/次 大于了最小时间规定,所以每一次触发都生效。

应用场景

对于函数防抖,有以下几种应用场景:

  • 给按钮加函数防抖防止表单多次提交。
  • 对于输入框连续输入进行AJAX验证时,用函数防抖能有效减少请求次数。
  • 判断 scroll 是否滑到底部, 滚动事件 + 函数防抖

总的来说,适合多次事件 一次响应 的情况

对于函数节流,有如下几个场景:

  • 游戏中的刷新率
  • DOM元素拖拽
  • Canvas画笔功能

总的来说,适合 大量事件 按时间做 平均 分配触发。

源码

函数防抖:

function debounce(fn, wait) {
 var timer = null;
 return function () {
  var context = this
  var args = arguments
  if (timer) {
   clearTimeout(timer);
   timer = null;
  }
  timer = setTimeout(function () {
   fn.apply(context, args)
  }, wait)
 }
}
var fn = function () {
 console.log('boom')
}
setInterval(debounce(fn,500),1000) // 第一次在1500ms后触发,之后每1000ms触发一次
setInterval(debounce(fn,2000),1000) // 不会触发一次(我把函数防抖看出技能读条,如果读条没完成就用技能,便会失败而且重新读条)

之所以返回一个函数,因为防抖本身更像是一个函数修饰,所以就做了一次函数柯里化。里面也用到了闭包,闭包的变量是 timer 。

函数节流

function throttle(fn, gapTime) {
 let _lastTime = null;
 return function () {
 let _nowTime = + new Date()
 if (_nowTime - _lastTime > gapTime || !_lastTime) {
  fn();
  _lastTime = _nowTime
 }
 }
}
let fn = ()=>{
 console.log('boom')
}
setInterval(throttle(fn,1000),10)

如图是实现的一个简单的函数节流,结果是 一秒打出一次boom

总结

以上所述是小编给大家介绍的JS函数节流和函数防抖问题分析,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
jquery1.4后 jqDrag 拖动 不可用
Feb 06 Javascript
javascript与CSS复习(三)
Jun 29 Javascript
javascript 进阶篇1 正则表达式,cookie管理,userData
Mar 14 Javascript
CodeMirror2 IE7/IE8 下面未知运行时错误的解决方法
Mar 29 Javascript
JS实现清除指定cookies的方法
Sep 20 Javascript
JS简单实现动画弹出层效果
May 05 Javascript
jquery实现多条件筛选特效代码分享
Aug 28 Javascript
微信小程序 wx.request(object) API详解及实例代码
Sep 30 Javascript
vue移动端路由切换实例分析
May 14 Javascript
浅谈一个webpack构建速度优化误区
Jun 24 Javascript
微信浏览器左上角返回按钮监听的实现
Mar 04 Javascript
在react中使用vue的状态管理的方法示例
May 02 Javascript
vue 将页面公用的头部组件化的方法
Dec 18 #Javascript
浅谈使用React.setState需要注意的三点
Dec 18 #Javascript
vue 项目如何引入微信sdk接口的方法
Dec 18 #Javascript
微信小程序实现给嵌套template模板传递数据的方式总结
Dec 18 #Javascript
微信小程序实现页面跳转传值以及获取值的方法分析
Dec 18 #Javascript
10个在JavaScript开发中常遇到的BUG
Dec 18 #Javascript
详解webpack与SPA实践之开发环境搭建
Dec 18 #Javascript
You might like
解析MySql与Java的时间类型
2013/06/22 PHP
JavaScript中null与undefined分析
2009/07/25 Javascript
两种WEB下的模态对话框 (asp.net或js的分别实现)
2009/12/02 Javascript
基于JQuery实现鼠标点击文本框显示隐藏提示文本
2012/02/23 Javascript
Jquery 自定义动画概述及示例
2013/03/29 Javascript
3种Jquery限制文本框只能输入数字字母的方法
2014/12/03 Javascript
javascript每日必学之封装
2016/02/23 Javascript
javascript简单实现等比例缩小图片的方法
2016/07/27 Javascript
vue translate peoject实现在线翻译功能【新手必看】
2018/06/07 Javascript
使用vue-router完成简单导航功能【推荐】
2018/06/28 Javascript
基于AngularJS拖拽插件ngDraggable.js实现拖拽排序功能
2019/04/02 Javascript
jQuery实现每日秒杀商品倒计时功能
2019/09/06 jQuery
js闭包的9个使用场景
2020/12/29 Javascript
JS实现公告上线滚动效果
2021/01/10 Javascript
[16:19]教你分分钟做大人——风暴之灵
2015/03/11 DOTA
[01:46]辉夜杯—打造中国DOTA新格局
2015/12/25 DOTA
[01:11:11]Alliance vs RNG 2019国际邀请赛淘汰赛 败者组BO1 8.20.mp4
2020/07/19 DOTA
在Windows服务器下用Apache和mod_wsgi配置Python应用的教程
2015/05/06 Python
python多进程读图提取特征存npy
2019/05/21 Python
python实现在cmd窗口显示彩色文字
2019/06/24 Python
详解python中docx库的安装过程
2019/11/08 Python
python主线程与子线程的结束顺序实例解析
2019/12/17 Python
关于python 跨域处理方式详解
2020/03/28 Python
Python selenium环境搭建实现过程解析
2020/09/08 Python
python3.8.3安装教程及环境配置的详细教程(64-bit)
2020/11/28 Python
纯CSS3实现图片无间断轮播效果
2016/08/25 HTML / CSS
CSS书写规范、顺序和命名规则
2014/03/06 HTML / CSS
台湾SHOPRO购物行家:亚洲首创影视.3C.家电.优质购物平台
2018/05/07 全球购物
C#软件工程师英语面试题
2015/06/07 面试题
函授生自我鉴定
2014/03/25 职场文书
优秀应届生求职信
2014/06/16 职场文书
销售活动策划方案
2014/08/26 职场文书
大四优秀党员个人民主评议
2014/09/19 职场文书
雷锋电影观后感
2015/06/10 职场文书
结婚司仪主持词
2015/06/29 职场文书
python 实现的截屏工具
2021/05/08 Python