抱歉,如果之前有人问过这个问题 - 我还没有找到适合我的情况的答案。
我有一个函数,它将被一次又一次异步调用。
我需要避免并发执行这个函数。
这里是例子:
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/