简体   繁体   English

如何实现类似油门的功能,但又不会在调用之间浪费时间

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM