对我来说,这两个似乎是在做同样的事情。我查了这两个博客,但我仍然难以理解。
http://remysharp.com/2010/07/21/throttling-function-calls
http://benalman.com/projects/jquery-throttle-debounce-plugin/
http://remysharp.com/2010/07/21/throttling-function-calls
http://benalman.com/projects/jquery-throttle-debounce-plugin/
delay
的参数。
防抖。延迟是等待直到没有更多的调用,然后再进行调用。就像关闭电梯门一样:门必须等待没有人试图进入才能关闭。function debounce(fn, delay) {
let handle = null
return function () {
if (handle) {
handle = clearTimeout(handle)
}
handle = setTimeout(() => {
fn(...arguments)
}, delay)
}
}
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)
}
}
}
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
}
我开始相信节流是在防抖的基础上的一个附加功能。阅读这篇文章https://windmaomao.medium.com/throttle-is-a-debounce-add-on-80d4a6027ad4。
function throttle(fn, delay) {
let h
let queue = []
function pop() {
if (queue.length < 1) return
if (!h) {
const [that, args] = queue.pop()
fn.apply(that, args)
h = setTimeout(() => {
h = null
pop()
}, delay)
}
}
return function push() {
queue.push([this, arguments])
pop()
}
}
限流
限流是指在一段时间内,对某个函数的调用次数进行最大限制。比如“每100毫秒最多执行一次该函数”。假设在正常情况下,在10秒内你会调用该函数1000次。如果将该函数的限流设为每100毫秒最多执行一次,则该函数最多只会被执行100次。
(10s * 1,000) = 10,000ms
10,000ms / 100ms throttling = 100 maximum calls
防抖
防抖确保一个函数在没有被调用的情况下经过一定时间后才能再次调用。比如说,"只有在100毫秒内没有被调用时才执行该函数"。
假设一个函数在3秒钟内以快速方式连续调用了1,000次,然后停止调用。如果你在100毫秒内进行了防抖处理,那么该函数将在3.1秒时执行一次,即整个突发调用结束后。每当在连续调用期间重新调用该函数时,它都会重置防抖计时器。
来源:- 节流和防抖的区别
假设我们有一个回调函数"cb",要在事件"E"上调用它。
如果事件“E”在1秒内触发了1000次,那么就会有1000次对“cb”的调用。也就是说,每毫秒调用一次。为了优化,我们可以使用以下两种方法之一:
throttle是debounce
的一个封装,它使得debounce
在一定时间内调用传递过来的function
。如果debounce
延迟了一个比指定的时间更长的函数调用周期。
去抖动和节流是从一系列事件中选择目标以进行减少的方法。它们都需要一个时间段作为参数,例如:x
毫秒,并且需要leading
/ tailing
变量来定义如何选择事件。
当在接下来的x
毫秒内没有其他事件发生时,选择一个事件。
"--->": timeline
"o,c,e": events, where
"o" are events selected by "leading"
"e" are events selected by "tailing"
"c" are skipped events
"|===|": period (x=5)
--oc-e-----occ-e----o-cc--ce-----o-c-cce------> source events
|===| |===| |===| |===|
||===| ||===| | |===| | |===|
| |===| | |===| | |===| | |===|
| | | |===|| |===| | |===|
| | | || |===| | |===|
--o--------o--------o------------o------------> selected events (leading)
---------e---------e-----------e-----------e--> selected events (tailing)
每当事件发生时,在每 x
毫秒内选择一个事件
--oc-e-----occ-e----o-ce--oe-----o-c-eoe------> source events
|===| |===| |===| |===| |===||===|
--o--------o--------o-----o------o----o-------> selected events (leading)
------e--------e--------e-----e------e----e---> selected events (tailing)
lodash库建议阅读以下文章:https://css-tricks.com/debouncing-throttling-explained-examples/,该文章详细解释了Debounce
和Throttle
之间的区别以及它们的起源。
去抖动是从数字信号中去除噪音的过程。当按下按钮时,信号的反弹会导致按钮被注册为被按下多次。去抖动可消除此噪音,使按钮只被注册为被按下一次。 想象一根尺子在桌子边缘上弹跳,想象开关内部的金属触点也像这样弹跳。
防抖使得一个函数只能在自上次被调用后的一定时间间隔后才能执行。
function debounce(func,wait){
let timeout
return(...arg) =>{
clearTimeout(timeout);
timeout= setTimeout(()=>func.apply(this,arg),wait)
}
}
function SayHello(){
console.log("Jesus is saying hello!!")
}
let x = debounce(SayHello,3000)
x()
设计模式限制了在一段时间内调用给定事件处理程序的最大次数。它允许处理程序周期性地按指定间隔调用,忽略在等待期结束之前发生的每个调用。
function throttle(callback, interval) {
let enableCall = true;
return (...args)=> {
if (!enableCall) return;
enableCall = false;
callback.apply(this, args);
setTimeout(() => enableCall = true, interval);
}
}
function helloFromThrottle(){
console.log("Jesus is saying hi!!!")
}
const foo = throttle(helloFromThrottle,5000)
foo()
callback.apply()
中使用 this
,也不要返回箭头函数。 - Bergi限流代码,
const trottle = function (fn, d) {
let flag = true; // to pass the first event
return function () {
if (flag) {
fn(); // execute the decorative function
flag = false; // block the next fired events
setTimeout(() => {
flag = true; // unblock the next fired events after a specified delay
}, d);
}
};
};
节流函数通常用于调整大小或滚动事件。
什么是防抖?
示例:下面的图片描述了只有在完成延迟(100毫秒)后才会触发点击事件。
用户触发了事件e1、e2、e3和e4,但由于连续事件发生在100毫秒内,所以它们没有成功执行。(例如e1和e2之间的延迟小于100毫秒,或者e2和e3之间的延迟小于100毫秒...等等) 事件e4成功调用了装饰函数,因为用户触发后经过了100毫秒的延迟。 防抖代码:
const debounce = function (fn, d) {
let timer;
return function () {
clearTimeout(timer); // clears/reset the timer if the event is triggered withing the delay
timer = setTimeout(() => { // execute the function
fn();
}, d);
};
};
https://www.geeksforgeeks.org/javascript-throttling/ https://www.geeksforgeeks.org/debouncing-in-javascript/