文章目录
概述Debounce瞬时响应or延迟响应举例与注意事项Throttle定义用法举例参考文章这两天在学习前端知识,在Vue的官方教程中看到了这两个概念,查阅相关资料后,做以下整理。本文适合刚接触到这个概念,但是不知道它们有啥区别的朋友阅读。我尽量讲得通俗易懂容易理解些,但是水平有限,不足之处欢迎批评指正。
概述
Debounce
和Throttle
是两个非常相似,但不相同的方法,它们都用来控制我们允许一个函数随时间执行的次数,用官方一点的说法就是:防止抖动。但是它们又有不同,以鼠标点击事件绑定的函数clickFunc()
为例:假设用户在10秒内不间断点击50下鼠标
debounce(clickFunc(),delay)
是将这50次鼠标在用户停止点击鼠标点击动作的delay
秒后,才响应一次。而throttle(clickFunc(),delay)
是在delay
秒的时间间隔内。无论用户点击多少次,只响应一次。
讲到这里可能还不是很清楚,但没关系,接下来这个例子可以帮助你更好地理解它们的区别
再举一个例子:比如我们现在有一个函数需要响应用户的滚动交互。我们都知道,用户可以通过鼠标滚轮和拖动侧边的长条形bar进行滚动交互。
如果滚动一个单位,我们就需要操作一次DOM元素。那么用户如果每秒滚动100个单位,是根本无法全部响应的,还会造成浏览器卡死。所以我们可以使用debounce()
,让用户停止滚动后再响应。经常刷微博逛知乎的朋友应该都知道,我们即将滑动到底部的时候,前端会请求更多内容以方便我们查阅。这是怎么做到的呢?其实就是用了throttle(func(),delay)
函数,其中func()
是一个检测是否快到底部的函数,delay
用来控制多长时间间隔内,浏览器响应一次。用户执行滚动事件的时候,就会判定是否靠近底部,如果靠近底部就发一个AJAX请求新一批内容。这也避免了这个函数一直监听,用户靠近底部的每一次滑动都去请求服务器,然后给服务器带来很多不必要的负担。
这两个函数在我们将某个函数绑定到操作DOM元素的事件上非常有用,为什么这么说呢?
这两个函数的出现,其实相当于我们在事件响应和函数执行间添加了一个控制层。显然这是非常有必要的,因为我们无法控制用户如何进行交互,但是我们可以控制前端如何响应这些用户的交互。
Debounce
可以理解成把一些连续的操作视为一组序列,最终浏览器只把这组序列视为一个事件进行响应。
如图,第一排为用户的时间,第二排为浏览器的响应
"归为一组响应"的理解:
为了方便理解debounce()
,在这里举个例子:想像现在有一个电梯,如果检测到当前有人进来就延迟5s关门。现在第一个人走进电梯,过了3s,还差2s关门的时候,电梯又走进来了一个人。那么在第二个人走进来之后,电梯会重设计时器,重新计时5s再关门。同理,第三个人如果在这5s间隔内走进电梯,电梯又会重新计时。
瞬时响应or延迟响应
其实这很容易带来一个问题,那就是现在我们介绍的debounce()
函数事实上是延迟响应的。也就是说当我们进行连续的交互后,要过一定时间才会响应我们的交互事件。那如果我们要让它马上就响应一次我们的交互呢?debounce()
给我们提供了参数让我们来控制是瞬时响应还是延迟响应。
下面放上一张瞬时响应的示意图,可以看到,虽然还是把这些交互归为了一组,只响应一次。但响应的是用户一开始触发交互事件:
举例与注意事项
debounce()
可以用于用户输入,用户调整浏览器窗口大小等。
比如在用户注册界面,等用户停止输入邮箱后,判断用户输入的内容是否符合邮箱校验规则。
在使用时,我们要注意一个地方。就是debounce()
不能被多次调用,下面给出了一种正确用法与一种错误用法,请读者自行体会。
WRONG
$(window).on('scroll', function() {_.debounce(doSomething, 300); });
RIGHT
$(window).on('scroll', _.debounce(doSomething, 200));
Throttle
定义
这前面简单介绍过了,这里就不过多赘述。它的定义是:
不允许某个函数在{delay}长度的时间间隔内执行超过一次
用法举例
它的用法与debounce()
相似,以lodash.js为例:
_.throttle(dosomething, 16)
主要用在检测用户界面是否已经靠近底部了,如果靠近底部就需要请求新的内容供用户查阅。
参考文章
Debouncing and Throttling Explained Through Examples
如果觉得《浅析Debounce 与 Throttle的区别》对你有帮助,请点赞、收藏,并留下你的观点哦!