详解JS函数防抖


Posted in Javascript onJune 05, 2020

一、什么是函数防抖

       概念:函数防抖(debounce),就是指触发事件后,在 n 秒内函数只能执行一次,如果触发事件后在 n 秒内又触发了事件,则会重新计算函数延执行时间。

       举个栗子,坐电梯的时候,如果电梯检测到有人进来(触发事件),就会多等待 10 秒,此时如果又有人进来(10秒之内重复触发事件),那么电梯就会再多等待 10 秒。在上述例子中,电梯在检测到有人进入 10 秒钟之后,才会关闭电梯门开始运行,因此,“函数防抖”的关键在于,在 一个事件 发生 一定时间 之后,才执行 特定动作

二、为什么需要函数防抖

前端开发过程中,有一些事件,常见的例如,onresize,scroll,mousemove ,mousehover 等,会被频繁触发(短时间内多次触发),不做限制的话,有可能一秒之内执行几十次、几百次,如果在这些函数内部执行了其他函数,尤其是执行了操作 DOM 的函数(浏览器操作 DOM 是很耗费性能的),那不仅会浪费计算机资源,还会降低程序运行速度,甚至造成浏览器卡死、崩溃。这种问题显然是致命的。

       除此之外,短时间内重复的 ajax 调用不仅会造成数据关系的混乱,还会造成网络拥塞,增加服务器压力,显然这个问题也是需要解决的。

三、函数防抖如何解决上述问题

       根据上面对问题的分析,细细思索,可以想到如下解决方案。

       函数防抖的要点,是需要一个 setTimeout 来辅助实现,延迟运行需要执行的代码。如果方法多次触发,则把上次记录的延迟执行代码用 clearTimeout 清掉,重新开始计时。若计时期间事件没有被重新触发,等延迟时间计时完毕,则执行目标代码。

四、函数防抖的代码实现

       根据以上分析,我们对 “函数防抖” 来进行简单的代码实现,如下:

function debounce(fn,wait){
 var timer = null;
 return function(){
  if(timer !== null){
   clearTimeout(timer);
  }
  timer = setTimeout(fn,wait);
 }
}
 
function handle(){
 console.log(Math.random());
}
 
window.addEventListener("resize",debounce(handle,1000));

五、函数节流的使用场景

       函数防抖一般用在什么情况之下呢?一般用在,连续的事件只需触发一次回调的场合。具体有:

       搜索框搜索输入。只需用户最后一次输入完,再发送请求;

       用户名、手机号、邮箱输入验证;

       浏览器窗口大小改变后,只需窗口调整完后,再执行 resize 事件中的代码,防止重复渲染。

       目前遇到过的用处就是这些,理解了原理与实现思路,小伙伴可以把它运用在任何需要的场合,提高代码质量。

总结

       函数防抖其实是分为 “立即执行版” 和 “非立即执行版” 的,根据字面意思就可以发现他们的差别,所谓立即执行版就是 触发事件后函数不会立即执行,而是在 n 秒后执行,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。 而 “非立即执行版” 指的是 触发事件后函数会立即执行,然后 n 秒内不触发事件才能继续执行函数的效果。。

       在开发过程中,我们需要根据不同的场景来决定我们需要使用哪一个版本的防抖函数,一般来讲上述的防抖函数都能满足大部分的场景需求。但我们也可以将非立即执行版和立即执行版的防抖函数结合起来,实现最终的双剑合璧版本的防抖函数,以下为小伙伴们做了简单的实现:

/**
* @desc 函数防抖---“立即执行版本” 和 “非立即执行版本” 的组合版本
* @param func 需要执行的函数
* @param wait 延迟执行时间(毫秒)
* @param immediate---true 表立即执行,false 表非立即执行
**/
function debounce(func,wait,immediate) {
let timer;

return function () {
let context = this;
let args = arguments;

if (timer) clearTimeout(timer);
if (immediate) {
var callNow = !timer;
timer = setTimeout(() => {
timer = null;
}, wait)
if (callNow) func.apply(context, args)
} else {
timer = setTimeout(function(){
func.apply(context, args)
}, wait);
}
}
}

function handle(){
console.log(Math.random());
}

// window.addEventListener("mousemove",debounce(handle,1000,true)); // 调用立即执行版本
window.addEventListener("mousemove",debounce(handle,1000,false)); // 调用非立即执行版本

以上就是详解JS函数防抖的详细内容,更多关于JS函数防抖的资料请关注三水点靠木其它相关文章!

Javascript 相关文章推荐
JQuery 插件模板 制作jquery插件的朋友可以参考下
Mar 17 Javascript
js判断选择的时间是否大于今天的代码
Aug 20 Javascript
js实现浏览器的各种菜单命令比如打印、查看源文件等等
Oct 24 Javascript
解析jQuery的三种bind/One/Live事件绑定使用方法
Dec 30 Javascript
实例讲解JQuery中this和$(this)区别
Dec 08 Javascript
jQuery实现的Div窗口震动效果实例
Aug 07 Javascript
jquery.cookie.js用法实例详解
Dec 25 Javascript
新版vue-cli模板下本地开发环境使用node服务器跨域的方法
Apr 03 Javascript
Node.js log4js日志管理详解
Jul 31 Javascript
微信小程序五子棋游戏的悔棋实现方法【附demo源码下载】
Feb 20 Javascript
浅析webpack-bundle-analyzer在vue-cli3中的使用
Oct 23 Javascript
JavaScript继承的三种方法实例
May 12 Javascript
Vuex的各个模块封装的实现
Jun 05 #Javascript
js实现表单项的全选、反选及删除操作示例
Jun 05 #Javascript
一篇文章带你使用Typescript封装一个Vue组件(简单易懂)
Jun 05 #Javascript
vscode 插件开发 + vue的操作方法
Jun 05 #Javascript
vue渲染方式render和template的区别
Jun 05 #Javascript
Vue是怎么渲染template内的标签内容的
Jun 05 #Javascript
Vue 如何使用props、emit实现自定义双向绑定的实现
Jun 05 #Javascript
You might like
PHP设计模式之代理模式的深入解析
2013/06/13 PHP
提高PHP编程效率的方法
2013/11/07 PHP
PHP开发框架Laravel数据库操作方法总结
2014/09/03 PHP
仿服务器端脚本方式的JS模板实现方法
2007/04/27 Javascript
javascript 贪吃蛇实现代码
2008/11/22 Javascript
jquery json 实例代码
2010/12/02 Javascript
重构Javascript代码示例(重构前后对比)
2013/01/23 Javascript
js实现单一html页面两套css切换代码
2013/04/11 Javascript
IE下window.onresize 多次调用与死循环bug处理方法介绍
2013/11/12 Javascript
Area 区域实现post提交数据的js写法
2014/04/22 Javascript
javascript设置连续两次点击按钮时间间隔的方法
2014/10/28 Javascript
基于JavaScript操作DOM常用的API小结
2015/12/01 Javascript
解决js页面滚动效果scrollTop在FireFox与Chrome浏览器间的兼容问题的方法
2015/12/03 Javascript
仅30行代码实现Javascript中的MVC
2016/02/15 Javascript
AngularJs Understanding the Controller Component
2016/09/02 Javascript
jQuery实现输入框邮箱内容自动补全与上下翻动显示效果【附demo源码下载】
2016/09/20 Javascript
基于easyui checkbox 的一些操作处理方法
2017/07/10 Javascript
对于Javascript 执行上下文的全面了解
2017/09/05 Javascript
详解node.js的http模块实例演示
2018/07/12 Javascript
在vue中使用Autoprefixed的方法
2018/07/27 Javascript
layui table设置前台过滤转义等方法
2018/08/17 Javascript
手把手教你 CKEDITOR 4 扩展插件制作
2019/06/18 Javascript
Python 40行代码实现人脸识别功能
2017/04/02 Python
python构建深度神经网络(DNN)
2018/03/10 Python
python创造虚拟环境方法总结
2019/03/04 Python
Python列表原理与用法详解【创建、元素增加、删除、访问、计数、切片、遍历等】
2019/10/30 Python
Django基于Models定制Admin后台实现过程解析
2020/11/11 Python
特步官方商城:Xtep
2017/03/21 全球购物
巴西补充剂和维生素购物网站:Natue
2019/06/17 全球购物
大二法英学生职业生涯规划范文
2014/02/27 职场文书
2014年小学辅导员工作总结
2014/12/23 职场文书
毕业生捐书活动倡议书
2015/04/27 职场文书
公司的力量观后感
2015/06/05 职场文书
谁动了我的奶酪读书笔记
2015/06/30 职场文书
2016优秀大学生个人事迹材料范文
2016/03/01 职场文书
python如何利用cv2.rectangle()绘制矩形框
2022/12/24 Python