javascript - 排队js函数

标签 javascript

抱歉,如果之前有人问过这个问题 - 我还没有找到适合我的情况的答案。

我有一个函数,它将被一次又一次异步调用。
我需要避免并发执行这个函数。

这里是例子:

const q = // some kind of queue;

let v = 0;
const fun = (arg) => {
    console.log('v', v)
    setTimeout(() => {
        v = v + arg;
        // return true;
        q.next()
    }, 1000)
}


q.add(fun(2))
q.add(fun(3))
q.add(fun(4))
q.add(fun(5))

这是我想在最后看到的日志:

v 0
v 2
v 5
v 9
v 14

最佳答案

您可以只使用数组。

请注意,我的代码的输出与您的略有不同 - 我没有得到“v 14”。我不确定您为什么期望该输出...您正在排队四个函数调用但期望五行输出?

const q = [];

let v = 0;
function fun (arg) {
  console.log('v', v);
  setTimeout(() => {
    v = v + arg;
    var next = q.shift();
    if (next) { next(); }
  });
}

q.push(() => { fun(2); });
q.push(() => { fun(3); });
q.push(() => { fun(4); });
q.push(() => { fun(5); });

q.shift()(); // run the first one

// OUTPUT:
// v 0
// v 2
// v 5
// v 9

编辑

这可能是一个更好的版本,它具有额外的优点,无论何时排队,它都可以正常工作。在上面的代码中,您必须手动开始运行事物,一旦队列耗尽,后面添加的任何内容都不会运行。在下面的 FunctionQueue 类中,只要至少有一个函数要运行,就会自动执行:

class FunctionQueue {
  constructor() {
    this.queue = [];
    this.running = false;
  }

  go() {
    if (this.queue.length) {
      this.running = true;
      this.queue.shift()(() => { this.go(); });
    } else {
      this.running = false;
    }
  }

  add(func) {
    this.queue.push(func);

    if(!this.running) {
      this.go();
    }
  }
}

let v = 0;
function fun (arg, cb) {
  console.log('v', v);
  v += arg;
  setTimeout(cb, 100);
}

const q = new FunctionQueue();
// Execution will automatically start once something is enqueued.
q.add((cb) => { fun(2, cb); });
q.add((cb) => { fun(3, cb); });
q.add((cb) => { fun(4, cb); });
q.add((cb) => { fun(5, cb); });

// At this point, nothing's running anymore.

// Enqueueing something much later will resume execution again.
setTimeout(() => {
  q.add((cb) => { fun(6, cb); });
}, 1000);

// OUTPUT:
// v 0
// v 2
// v 5
// v 9
// v 15

关于javascript - 排队js函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38060772/

相关文章:

javascript - 更改 contentEditable div 的字体大小

java - 在 Javascript 中请求 URL,使用 Java Applet 获取 URL 内容,返回 Javascript?

php - 使用 PHP 创建 cookie,但从 javascript 读取时遇到困难

javascript - 如何使用 Jest 测试同一个类中的方法调用?

javascript - Jquery toggle() 不适用于 YouTube 订阅按钮

javascript - 如何在模态淡入淡出中隐藏元素

javascript - chop ul li anchor 标记中的文本

javascript - 使用 .splice 从数组中删除一个项目是删除多个对象

javascript - 优化 JQuery 中的每个循环

javascript - 使用 jquery 动态生成目标内容