上下文:我在javascript tutorial
的任务下编写了一个简单的节流阀任务:编写一个像这样的节流阀:
function f(a) {
console.log(a)
};
// f1000 passes calls to f at maximum once per 1000 ms
let f1000 = throttle(f, 1000);
f1000(1); // shows 1
f1000(2); // (throttling, 1000ms not out yet)
f1000(3); // (throttling, 1000ms not out yet)
// when 1000 ms time out...
// ...outputs 3, intermediate value 2 was ignored
// P.S. Arguments and the context this passed to f1000 should be passed to the original f.
这是我的解决方案。奇怪的是,当我在调试控制台中逐步运行它时,它可以正常运行,但不能正常运行。知道为什么以及如何解决它吗? (我认为这与setTimeout
有关?)
function throttle(f, ms) {
let isCoolDown = true,
queue = []
function wrapper(...args) {
queue.push(args)
if (!isCoolDown) return
isCoolDown = false
setTimeout(function() {
isCoolDown = true
if (queue[0] !== undefined) {
f.apply(this, queue.slice(-1))
queue = []
}
}, ms)
return function() {
f.apply(this, args)
queue = []
}()
}
return wrapper
}
答案 0 :(得分:1)
几件事:
1)交换isCoolDown = false
和isCoolDown = true
2)您不需要队列,只有一个电话必须经过,而其他电话会因节流而被丢弃
function throttle(fn, ms) {
let throttle = false;
let timer;
return wrapper(...args) {
if(!throttle) { // first call gets through
fn.apply(this, args);
throttle = true;
} else { // all the others get throttled
if(timer) clearTimeout(timer); // cancel #2
timer = setTimeout(() => {
fn.apply(this, args);
timer = throttle = false;
}, ms);
}
};
}
答案 1 :(得分:0)
此行有一个错误:
f.apply(this, queue.slice(-1))
.slice
方法将返回一个数组。由于args
是一个数组,因此queue.slice(-1)
的结果将类似于:
[ [1, 2, 3] ]
相反,您可以将其更改为:
f.apply(this, queue.slice(-1)[0])