浅析Debounce 与 Throttle的区别


这两天在学习前端知识,在Vue的官方教程中看到了这两个概念,查阅相关资料后,做以下整理。本文适合刚接触到这个概念,但是不知道它们有啥区别的朋友阅读。我尽量讲得通俗易懂容易理解些,但是水平有限,不足之处欢迎批评指正。

概述

DebounceThrottle是两个非常相似,但不相同的方法,它们都用来控制我们允许一个函数随时间执行的次数,用官方一点的说法就是:防止抖动。但是它们又有不同,以鼠标点击事件绑定的函数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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: debounce 和 throttle 是两种用于限制函数调用频率的技术。 debounce 函数会在一定时间内把多次函数调用合并成一次。例如,我们希望限制用户在输入框中输入的频率,以免服务器压力过大。我们可以使用 debounce 函数,设置一个延迟时间,在用户停止输入后一段时间内只执行一次回调函数。 throttle 函数会在一定时间内限制函数的调用次数。例如,我们希望限制用户滚动页面时图片懒加载的频率,以免影响性能。我们可以使用 throttle 函数,设置一个执行频率,在规定时间内只执行一次或几次回调函数。 ### 回答2: debounce函数和throttle函数都是用于处理频繁触发的事件,以减轻性能负担和提高用户体验的函数。 debounce函数会在规定的延迟时间内,只执行最后一次触发的事件。例如,在一个输入框中实时搜索关键字,如果在用户连续输入时立即处理搜索逻辑,可能会导致多次无意义的请求。使用debounce函数可以在用户输入完成后的一段时间内,再处理搜索逻辑,避免了频繁操作。 throttle函数会在规定的时间间隔内,按照规定的频率执行事件。例如,在滚动页面时,如果在每次滚动时都触发一次事件,可能会导致页面卡顿。使用throttle函数可以控制触发事件的频率,比如每隔200毫秒触发一次事件,以减轻页面负担。 举个例子来说明其用法: 假设有一个按钮需要防止多次点击: ```html <button id="btn">点击</button> ``` 使用debounce函数来防止多次点击: ```javascript function debounce(func, delay) { let timerId; return function (...args) { clearTimeout(timerId); timerId = setTimeout(() => { func.apply(this, args); }, delay); }; } function handleClick() { console.log("按钮被点击"); } const btn = document.getElementById("btn"); btn.addEventListener("click", debounce(handleClick, 200)); ``` 在这个例子中,通过使用debounce函数,当按钮被多次点击时,只有在最后一次点击后的200毫秒内才会触发handleClick函数,避免了多次点击产生多个事件的问题。 类似地,使用throttle函数可以控制按钮点击的频率,保证每隔一定时间间隔才能触发事件。 ### 回答3: debounce 函数和 throttle 函数是用来控制函数调用频率的工具函数。 debounce 函数的作用是延迟执行函数,当事件被触发后,函数不会立即被执行,而是延迟一段时间后执行。如果在延迟期间内又触发了相同的事件,那么之前的延迟会被取消,重新开始计时。这样可以避免在连续触发事件时频繁执行函数,提高性能。 举个例子,比如在网页输入框中实时搜索功能的实现。当用户输入时,我们希望能够在用户停止输入一段时间后才执行搜索操作,以避免频繁请求服务器。这时可以使用 debounce 函数来延时执行搜索函数,只有在用户停止输入一段时间后才真正执行搜索操作。 throttle 函数的作用是限制函数的执行频率,即无论触发多少次事件,函数都不会连续执行,而是固定时间间隔内执行一次。它可以用来控制一个函数在短时间内不能被频繁调用,以避免性能问题。 举个例子,比如在网页上绑定鼠标滚动事件时,如果没有对事件进行处理,每次鼠标滚动都会触发滚动事件,而滚动事件可能会执行一些复杂的操作,这样会导致性能问题。这时可以使用 throttle 函数来限制滚动事件的触发频率,比如每隔 100ms 执行一次滚动事件处理函数,这样可以降低函数的执行次数,提高性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值