我想每100毫秒限制一次我的功能。在下面的代码中,我希望仅打印1和3。但是实际结果中还会打印2。
function say(what) {
console.log(what);
}
const t = _.throttle(say, 100);
setTimeout(() => {
t(1);
}, 50);
setTimeout(() => {
t(1);
}, 50);
setTimeout(() => {
t(1);
}, 50);
setTimeout(() => {
t(1);
}, 55);
setTimeout(() => {
t(2);
}, 55);
setTimeout(() => {
t(3);
}, 500);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.11.1/lodash.js"></script>
我必须将油门等待时间更改为500,以滤除2。
也许我对油门的理解是错误的。节流阀是否应该在每个等待时间内最多执行一次该功能?
答案 0 :(得分:4)
您对如何使用此油门设置的理解不太正确。
直接回答:
每个等待周期内节气门最多执行一次该功能吗?
在未传递任何选项的情况下,如果在该时间段内多次调用了节流功能,则节流将在等待时间段的开始和结束(两次)执行。
在50ms处,您的第一个函数被调用,并且“ throttle”立即运行它,这时您的下一个f(1)也被排队等待在100ms处被调用。但是然后调用了另一个f(1),又调用了另一个f(1)然后调用了f(2),并且每个新变量都将最后一个替换为要在100ms处调用的函数(这是您进入油门的时间) )。然后经过100毫秒,然后在适当的时候调用f(3)或多或少。
如果您没有将任何选项传递给_.throttle
,它将立即调用第一个函数运行(0毫秒),然后在设置的时间段内调用最后一个函数运行。
以@zfrisch的代码作为开始:
function say(what) {
console.log(what);
}
const t = _.throttle(say, 100);
const TO = (n, i) => setTimeout(() => {
t(n);
}, i);
TO(1, 50); // logged immediately
TO(1, 50);
TO(1, 50);
TO(1, 55);
TO(2, 55); // logged at 100ms (as it was the last function attempted)
function say(what) {
console.log(what);
}
const t = _.throttle(say, 100, { leading: false });
const TO = (n, i) => setTimeout(() => {
t(n);
}, i);
TO(1, 50); // not logged at all
TO(1, 50);
TO(1, 50);
TO(1, 55);
TO(2, 55); // logged at 100ms (as it was the last function attempted)
function say(what) {
console.log(what);
}
const t = _.throttle(say, 100, { trailing: false });
const TO = (n, i) => setTimeout(() => {
t(n);
}, i);
TO(1, 50); // logged immediately
TO(1, 50);
TO(1, 50);
TO(1, 55);
TO(2, 55); // not logged at all
答案 1 :(得分:3)
节气门将延迟执行等待时间,但仍会调用该函数。在您的示例中,将发生以下情况:脚本启动后50毫秒记录了第一个1,此时节流阀将开始计数100毫秒。在此期间对t的任何呼叫都将被延迟。经过100毫秒后,将触发对t的最后一次调用。再过100ms,t不被调用,因此什么也没发生,最后一次调用发生了。
答案 2 :(得分:1)
很容易看到您假设代码将如何工作。理解它并不是一件难事,但之所以没有按照您期望的方式执行,是因为该函数的默认行为。
Throttle
函数:从上面您可以看到Throttle
花费了function
和wait
时间(以毫秒为单位)作为其前两个参数,但是options
在您的当前的代码,这些是解决问题的关键。
_.throttle
具有选项leading
和trailing
。这两个默认都设置为true
。
不幸的是,除非您熟悉幕后的过程,否则命名的选项尽管很恰当,但仅凭其名称并不是很明确。
leading
是指在适用时间调用的那些。这些是:
trailing
是指在时间间隔内进行的throttle
函数的最后一次调用。此函数不是简单地废弃,而是推迟到可以调用 为止。将其视为可在间隔期间填充的插槽。在间隔期间进行呼叫时,该插槽将被新功能填充/替换。
这可以说明:
function 1
进行呼叫function 2
进行呼叫function 2
取代function 1
作为尾随功能100ms
function 2
运行。以下是一个重要概念,并且最终是代码中所发生问题的症结所在:
如果两个选项均为true
,则在间隔期间进行跟踪的功能将称为之前新的引导调用throttle
函数。
因此,在下一个时间间隔结束时,新的 leading 调用将成为 trailing 调用。
我从lodash官方网站直接获得的文档确实对此进行了说明,但是您会被误解原谅,因为如果您不熟悉它们的术语,那么您会理解很多内容:
*See the Throttle Documentation on Lodash
在您的示例中,当您调用_.throttle
时,它将默认情况下,等待执行该函数调用,直到间隔过去,并在执行过程中连续重写等待调用的函数。 100ms
个间隔。要更改此设置并仅接受/执行间隔后进行的呼叫,可以将trailing
更改为false
。
function say(what) {
console.group();
console.log(what);
console.timeLog("check");
console.groupEnd();
}
const t = _.throttle(say, 100, {trailing: false});
const TO = (n, i) => setTimeout(()=>{t(n);}, i);
console.time("check");
TO(1,50);
TO(1,50);
TO(1,50);
TO(1,55);
TO(2,55);
TO(3,500);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>