[英]How to implement a throttle-like function but without loosing time between calls
I would like to implement a helper function like lodash's throttle, but which calls the passed callback only if the last call ended (and if not, delays the new call until then), instead of having a rule like "one call every x milliseconds".我想实现一个像 lodash 的油门这样的辅助函数,但它只在最后一次调用结束时才调用传递的回调(如果没有,则将新调用延迟到那时),而不是像“每 x 毫秒调用一次”这样的规则.
What's the best approach here?这里最好的方法是什么? Thanks.
谢谢。
So What you eventually want is to queue your function calls and call them from the stack.所以你最终想要的是将你的函数调用排队并从堆栈中调用它们。
// keep a stack of inputs for the function calls var stack = [], timer = null; function process() { var item = stack.shift(); // // process the item here // if (stack.length === 0) { clearInterval(timer); timer = null; } } // every time you call the function on event. instead of calling the processing function // call this to add it in a queue function queue(item) { stack.push(item); if (timer === null) { timer = setInterval(process, 500); } }
You can make this function work for multiple types of calls too.您也可以使此功能适用于多种类型的调用。 // use item as a deciding factor
// 使用 item 作为决定因素
// keep a stack of inputs for the function calls var stack = [], timer = null; function reset(item){ // reset item here } function process() { var item = stack.shift(); // // process the item here // switch (item.call) { case 'reset': reset(item); break; case 'stop': // stop(item); break; default: // code block // deal with it } if (stack.length === 0) { clearInterval(timer); timer = null; } } // every time you call the function on event. instead of calling the processing function // call this to add it in a queue // for hybrid calls // use item = {'call': 'reset', 'data': item} function queue(item) { stack.push(item); if (timer === null) { timer = setInterval(process, 500); } }
try using boolean variable like尝试使用布尔变量,如
var running = false;
use setInterval
or similar function and put condition if(!running){}
for statements to be performed.使用
setInterval
或类似函数并为要执行的语句放置条件if(!running){}
。 if statement is going to run then make running = true
. if 语句要运行然后 make
running = true
。
Finally worked out a way :终于想出了一个办法:
class Scheduler {
private readonly stack: Function[] = [];
private enqueue(task: Function) {
if (this.stack.length < 2) this.stack.push(task);
else this.stack[1] = task;
}
private dequeue() {
if (this.stack.length) {
const task = this.stack.shift()!;
task();
defer(() => this.dequeue());
}
}
run(task: Function) {
this.enqueue(task);
defer(() => this.dequeue());
}
}
// Usage :
const scheduler = new Scheduler()
// Very frequent call :
scheduler.run(() => { /* your heavy task */ })
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.