谁能给我一个简单的解释,关于节流和debounging函数之间的区别,以限制速率的目的。
在我看来,两者的作用是一样的。我查看了这两个博客来找出答案:
http://remysharp.com/2010/07/21/throttling-function-calls
http://benalman.com/projects/jquery-throttle-debounce-plugin/
谁能给我一个简单的解释,关于节流和debounging函数之间的区别,以限制速率的目的。
在我看来,两者的作用是一样的。我查看了这两个博客来找出答案:
http://remysharp.com/2010/07/21/throttling-function-calls
http://benalman.com/projects/jquery-throttle-debounce-plugin/
当前回答
这篇文章解释得很好,也有图形。
https://css-tricks.com/debouncing-throttling-explained-examples/
从文章中(并进行了一些澄清):
这(节流)和deboundation之间的主要区别在于节流保证了函数的定期执行,至少每X毫秒执行一次。
通常debounce在指定时间结束时调用函数,而throttle在第一次调用节流函数时调用。有时debounce可以采取额外的配置,将此更改为在开始时执行调用。当使用特定的配置调用时,debounce的一些实现实际上可以做油门所做的事情(参见Lodash源代码)。
其他回答
节流强制在一段时间内可以调用函数的最大次数。就像“最多每100毫秒执行一次这个函数。”
deboundation强制函数不被再次调用,直到一段时间过去而没有被调用。就像“仅在100毫秒后未被调用时才执行该函数。”
ref
油门(1秒):你好,我是机器人。只要你一直打我,我就会继续和你说话,但每次一秒后。如果你在一秒之前ping我的回复,我仍然会在1秒的间隔内回复你。换句话说,我就是喜欢隔一定的时间间隔回复。
弹跳(1秒):嗨,我是那个^^机器人的表弟。只要你一直ping我,我就会保持沉默,因为我喜欢在你最后一次ping我一秒钟后才回复。我不知道,是因为我的态度有问题还是因为我不喜欢打断别人。换句话说,如果您在上次调用后的1秒内一直向我请求回复,您将永远不会得到回复。是的是的…去吧!说我粗鲁就好。
节流阀(10分钟):我是一台伐木机。我将系统日志发送到我们的后端服务器,每隔10分钟。
反弹(10秒):嗨,我不是那台伐木机的表亲。(在这个想象的世界中,并不是每个脱锁器都与节流器有关)。我在附近一家餐馆当服务员。我应该让你知道,只要你一直在你的订单中添加东西,我就不会去厨房执行你的订单。只有在您上次修改订单后10秒后,我才会认为您已经完成了订单。到那时我才会去厨房执行您点的菜。
酷演示:https://css-tricks.com/debouncing-throttling-explained-examples/
服务员类比的功劳:https://codeburst.io/throttling-and-debouncing-in-javascript-b01cad5c8edf
将debounce和throttle放在一起可能会非常令人困惑,因为它们都共享一个称为延迟的参数。
防反跳。延迟是等到不再有调用时,再调用它。就像关闭电梯门一样:门必须等到没有人试图进入时才能关闭。
节流。延迟是以一定的频率等待,然后调用最后一个。很像手枪射击,枪只是不能超过一定的射速。
让我们看一看实现的细节。
function debounce(fn, delay) {
let handle = null
return function () {
if (handle) {
handle = clearTimeout(handle)
}
handle = setTimeout(() => {
fn(...arguments)
}, delay)
}
}
Debounce,继续中断超时,直到不再中断为止,然后触发fn。
function throttle(fn, delay) {
let handle = null
let prevArgs = undefined
return function() {
prevArgs = arguments
if (!handle) {
fn(...prevArgs)
prevArgs = null
handle = setInterval(() => {
if (!prevArgs) {
handle = clearInterval(handle)
} else {
fn(...prevArgs)
prevArgs = null
}
}, delay)
}
}
}
Throttle,存储最后一个调用参数,并设置一个间隔来触发,直到没有过去的调用。
相似之处。它们都有延迟时间,并且在延迟期间不会发生火灾,特别是当只有一场火灾时。两者都不聚合过去的事件,因此事件的数量可能与实际的火灾不同。
的区别。在有重复事件的弹跳情况下,延迟可以延长。而在节流阀情况下的延迟是固定的。所以一般来说,油门产生的火焰比反弹产生的火焰要多。
很容易记住。将组捆绑为一个。节流保持捆绑调用在一定的频率。
更新1-20-23
Throttle可能不需要setInterval,这是我最近写的一个新版本,它也照顾到了这个问题。
function throttle(fn, delay) {
let canFire = true
let queue = []
function pop() {
if (queue.length < 1) return
const [that, args] = queue.pop()
fn.apply(that, args)
canFire = false
setTimeout(() => {
canFire = true
pop()
}, delay)
}
function push() {
queue.push([this, arguments])
if (canFire) pop()
}
push.cancel = () => {
queue = []
}
return push
}
lodash库建议以下文章https://css-tricks.com/debouncing-throttling-explained-examples/详细解释Debounce和Throttle之间的区别及其起源
防反跳:
如果函数没有在间隔内被调用,则在间隔后执行函数。
节流:
以固定的时间间隔执行函数n次。