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 相关文章推荐
网站被黑的假象--ARP欺骗之页面中加入一段js
May 16 Javascript
javascript不同页面传值的改进版
Sep 30 Javascript
Firebug入门指南(Firefox浏览器)
Aug 21 Javascript
用jQuery中的ajax分页实现代码
Sep 20 Javascript
jQuery数据缓存功能的实现思路及简单模拟
May 27 Javascript
node.js中的fs.exists方法使用说明
Dec 17 Javascript
javascript实现支持移动设备画廊
Aug 24 Javascript
基于touch.js手势库+zepto.js插件开发图片查看器(滑动、缩放、双击缩放)
Nov 17 Javascript
Avalonjs双向数据绑定与监听的实例代码
Jun 23 Javascript
node链接mongodb数据库的方法详解【阿里云服务器环境ubuntu】
Mar 07 Javascript
Node.js文本文件BOM头的去除方法
Nov 22 Javascript
JavaScript实现简单计时器
Jun 22 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
《雄兵连》《烈阳天道》真的来了
2020/07/13 国漫
浅析PHP安装扩展mcrypt以及相关依赖项(PHP安装PECL扩展的方法)
2013/07/05 PHP
PHP将进程作为守护进程的方法
2015/03/19 PHP
php实现将上传word文件转为html的方法
2015/06/03 PHP
php面向对象程序设计中self与static的区别分析
2019/05/21 PHP
基于JQuery的数字改变的动画效果--可用来做计数器
2010/08/11 Javascript
js实现鼠标拖动图片并兼容IE/FF火狐/谷歌等主流浏览器
2013/06/06 Javascript
jQuery快速上手:写jQuery与直接写JS的区别详细解析
2013/08/26 Javascript
判断日期是否能跨月查询的js代码
2014/07/25 Javascript
限制上传文件大小和格式的jQuery插件实例
2015/01/24 Javascript
JavaScript获取文本框内选中文本的方法
2015/02/20 Javascript
js生成验证码并直接在前端判断
2015/05/15 Javascript
值得分享和收藏的Bootstrap学习教程
2016/05/12 Javascript
下一代Bootstrap的5个特点 超酷炫!
2016/06/17 Javascript
老生常谈JavaScript 正则表达式语法
2016/08/20 Javascript
基于jQuery制作小图标上下滑动特效
2017/01/18 Javascript
Angular @HostBinding()和@HostListener()用法
2018/03/05 Javascript
浅谈Vue开发人员的7个最好的VSCode扩展
2021/01/20 Vue.js
[02:54]DOTA2英雄基础教程 撼地者
2014/01/14 DOTA
Flask框架模板渲染操作简单示例
2019/07/31 Python
opencv转换颜色空间更改图片背景
2019/08/20 Python
appium+python adb常用命令分享
2020/03/06 Python
如何教少儿学习Python编程
2020/07/10 Python
Python requests接口测试实现代码
2020/09/08 Python
新加坡第一的杂货零售商:NTUC FairPrice
2020/12/05 全球购物
武汉英思工程科技有限公司–ORACLE面试测试题目
2012/04/30 面试题
XMLHttpRequest对象在IE和Firefox中创建方式有没有不同
2016/03/23 面试题
儿科护士自我鉴定
2013/10/14 职场文书
会计应届生的自荐信
2013/12/13 职场文书
入党积极分子学习两会心得体会范文
2014/03/17 职场文书
2014国庆节餐厅促销活动策划方案
2014/09/16 职场文书
办护照工作证明
2014/10/01 职场文书
公司前台接待岗位职责
2015/04/03 职场文书
党员干部廉洁自律承诺书
2015/04/28 职场文书
学校学期工作总结
2015/08/13 职场文书
如何解决goland,idea全局搜索快捷键失效问题
2022/04/03 Golang