当前位置: 首页 > 后端技术 > Node.js

JS专题debounce功能

时间:2023-04-03 10:58:12 Node.js

一、前言为什么会有debounce和throttling这样的工具功能?在用户与前端页面交互过程中,会非常频繁地触发很多操作,比如mousemove事件、滚动条滑动滚动事件、输入框输入事件、键盘keyup事件、浏览器窗口resize事件。将回调函数绑定到上述事件。如果回调函数需要大量计算、消耗内存、HTTP请求、DOM操作等,应用的性能和体验会很差。debounce和throttling函数的基本思想是降低高频事件处理函数handler的执行频率(注意是事件处理函数,不是事件回调函数),将多个事件的回调组合起来合并到一个回调中执行,从而优化性能。2、简单版的去抖动(debounce),也叫防抖,抖动指的是什么?抖动意味着运行不稳定。你可以理解为心神不定,静不下来。防抖的意思是防止抖动导致结果不准确,待结果稳定后再进行处理。比如在输入事件、鼠标移动、滚动条滑动、键盘敲击事件中,回调函数要等到stop事件触发,频率稳定为零后才会执行,也就是所谓的无后处理抖动。个人总结:Debounce是指只有在事件触发频率稳定后才执行回调函数,一系列的事件触发,但只进行一次事件处理。频率是单位时间内触发的次数。如果事件在单位时间内被触发多次,则只会执行最后一次。如果事件在单位时间内没有被触发超过一次,就会正常执行。Debounce分为延迟执行和立即执行。看一个debounced函数延迟执行的简单实现:

输入框:
上面代码中我的注释已经可以说明整个debounce过程了,我多说几句~debounce函数是在主线程的顺序执行过程中被调用的。传入的参数之一是事件触发时你真正要执行的事件处理函数。另一个参数是事件触发之间的间隔时间。如果在间隔时间内再次触发该事件,则重新开始计时,类似罚你5分钟内不准发言,时间到后可以开始发言。5分钟以内说话,会被罚款,5分钟以内不许说话,以此类推~debounce函数有一个定时器内部变量,定时器在返回的执行函数中使用。访问形成一个闭包。闭包的内容可以看我之前的文章《JavaScript之闭包》bebouncebebounce函数返回的匿名函数是输入事件的回调函数,所以匿名函数有一个默认的参数事件对象。同第4点,匿名函数是dom元素注册事件的回调函数,所以匿名函数(回调函数)的this指向HTMLInput元素。同第2点,触发函数后,如果在闭包中找到定时器变量,定时器变量的初始值为null,触发定时器后,定时器为当前定时器的id,id是一个数字。debounce过程是如果函数在定时器的间隔内被触发,它会清除上次触发事件时定义的定时器,并重新定义一个定时器。如果这次没有清零定时器,时间到后自然会执行事件处理函数。对这个过程有疑惑的同学可以通过打印出clearTimeout之前的timer变量来理解。事件处理函数(handler)的延迟执行,需要传递过去的call对象和event对象,这里call可以和apply互换,如果apply,传递arguments类数组即可。这样保证了参数的一致性,就好像没有经过debounce处理一样。以上就是debounce函数的基本思路,大家可以参考原理图。下图是HighDesign3中提到的throttling函数,其实就是本节提到的debounce函数。HighDesign3处理定时器变量用传入函数的属性替换那个。3.立即执行第2节中的debounce函数的简单版本可以满足大多数只需要触发一个事件处理的debounce场景:输入数据查询事件,下拉滚动条到窗口底部懒加载数据。但是有个问题,如果我要输入输入框的内容,输入第一个词后的数据怎么求呢?你可以理解,你可以立即开始说话,但你不能在说完之后再说5分钟。如果您在5分钟内发言,则您不能再发言5分钟。如果5分钟后你还不说话,那你可以先说话,然后再闭嘴5分钟~所以引入了debounce函数的立即执行版本。取消函数实现
输入框:
注释上面的代码可以说明整个过程,我们粗略的说一下:非立即执行版本和上一节一样,略过。timer的初始值为null,第一个trigger立即执行,!timer为true,可以立即调用事件处理器。每次触发事件时,都会重新分配计时器。在interval到期前,timer会是一个数字id,!timer为false,所以不能立即执行。如果间隔时间到了,则当前事件触发器的timerid会被置为null,可以立即执行下一个事件触发器。朋友们可以通过观察定时器值的变化来思考整个过程。定时器在debounce过程中作为一个标志,可以用来判断是否可以立即执行。看效果:取消函数如果debounce函数的间隔是5秒,想在这5秒内立即执行怎么办?所以我们在回调函数中添加一个取消函数属性。函数也是对象,可以像其他一般对象一样添加方法:
输入框:取消/div>看效果:debounce函数的意义在于将多个事件触发合并为一个事件处理,从而减少可能导致的大量重绘、http请求、内存占用、页面卡顿事件处理函数。另外,本文中关于this、call、apply、closures的知识,大家可以看我之前分享的文章。