setTimeout() 在 throttle 函数中被立即调用
setTimeout() being called immediately in throttle function
所以我正在尝试编写一个节流函数,该函数在调用时会调用回调,但在给定的时间间隔内最多只能调用特定的限制次数。如果达到限制,回调将被推入队列,在初始间隔后调用回调。
const throttle = (cb, interval, maxCalls) => {
let calls = 0;
const records = [];
let totalCalls = 0;
return (...rest) => {
if(calls < maxCalls) {
calls++;
records.push(Date.now());
totalCalls++;
cb.apply(null, rest);
setTimeout(() => {
calls--;
}, interval);
} else {
//cb within setTimeout being invoked immediately here
setTimeout(() => {
calls++;
records.push(Date.now());
totalCalls++;
cb.apply(null, rest);
//console.log(allotedTime: interval - (Date.now() - records[(totalCalls-1)-maxCalls]));
}, interval - (Date.now() - records[(totalCalls-1)-maxCalls]));
}
}
}
const meow = (start, ...args) => {
console.log(Date.now() - start, ...args);
}
const burp = throttle(meow.bind(this, Date.now()), 10000, 2);
setTimeout(() => burp('burp'), 0); // expect 2-7 'burp'
setTimeout(() => burp('burp'), 5000); // expect 5000 'burp'
setTimeout(() => burp('burp'), 6000); // expect 10000 'burp'
setTimeout(() => burp('burp'), 7000); // expect 15000 'burp'
主要问题是由于某种原因,在 else 块 中,该函数没有等待 setTimeout,而是立即被调用。语法看起来不错,所以我很难弄清楚为什么要调用它。这是被调用后的输出:
setTimeout(() => burp('burp'), 0); //6 'burp'
setTimeout(() => burp('burp'), 5000); //5001 'burp'
setTimeout(() => burp('burp'), 6000) //6001 'burp'
//allotedTime: 4005
setTimeout(() => burp('burp'), 7000); //10008 'burp'
//allotedTime: 4993
您会注意到,如果将 allotedTime 与上一行的结果相加,您将获得所需的日志。感谢您的观看。
不确定我是否完全理解问题,但根据您的期望,
else 间隔应该是:
interval - (Date.now() - records[totalCalls-maxCalls]))
因为一旦调用回调,totalCalls
就会递增。因此,要么将 totalCalls++;
添加为 else 块的第一条语句(在 setInterval()
之前),要么不要期望值会增加(建议编号 1)。
所以我正在尝试编写一个节流函数,该函数在调用时会调用回调,但在给定的时间间隔内最多只能调用特定的限制次数。如果达到限制,回调将被推入队列,在初始间隔后调用回调。
const throttle = (cb, interval, maxCalls) => {
let calls = 0;
const records = [];
let totalCalls = 0;
return (...rest) => {
if(calls < maxCalls) {
calls++;
records.push(Date.now());
totalCalls++;
cb.apply(null, rest);
setTimeout(() => {
calls--;
}, interval);
} else {
//cb within setTimeout being invoked immediately here
setTimeout(() => {
calls++;
records.push(Date.now());
totalCalls++;
cb.apply(null, rest);
//console.log(allotedTime: interval - (Date.now() - records[(totalCalls-1)-maxCalls]));
}, interval - (Date.now() - records[(totalCalls-1)-maxCalls]));
}
}
}
const meow = (start, ...args) => {
console.log(Date.now() - start, ...args);
}
const burp = throttle(meow.bind(this, Date.now()), 10000, 2);
setTimeout(() => burp('burp'), 0); // expect 2-7 'burp'
setTimeout(() => burp('burp'), 5000); // expect 5000 'burp'
setTimeout(() => burp('burp'), 6000); // expect 10000 'burp'
setTimeout(() => burp('burp'), 7000); // expect 15000 'burp'
主要问题是由于某种原因,在 else 块 中,该函数没有等待 setTimeout,而是立即被调用。语法看起来不错,所以我很难弄清楚为什么要调用它。这是被调用后的输出:
setTimeout(() => burp('burp'), 0); //6 'burp'
setTimeout(() => burp('burp'), 5000); //5001 'burp'
setTimeout(() => burp('burp'), 6000) //6001 'burp'
//allotedTime: 4005
setTimeout(() => burp('burp'), 7000); //10008 'burp'
//allotedTime: 4993
您会注意到,如果将 allotedTime 与上一行的结果相加,您将获得所需的日志。感谢您的观看。
不确定我是否完全理解问题,但根据您的期望, else 间隔应该是:
interval - (Date.now() - records[totalCalls-maxCalls]))
因为一旦调用回调,totalCalls
就会递增。因此,要么将 totalCalls++;
添加为 else 块的第一条语句(在 setInterval()
之前),要么不要期望值会增加(建议编号 1)。