很抱歉,如果之前有人问这个问题 - 我还没有找到我的答案。
我有一个函数,它将一次又一次地异步调用 我需要避免并发执行此函数。
这里的例子是:
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
答案 0 :(得分:1)
您可以使用数组。
请注意,我的代码输出与您的输出略有不同 - 我没有得到“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
答案 1 :(得分:0)
您可以使用Promise
。第一个解析,第二个解决,等等。
let v = 0;
const fun = (arg) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('v', v)
v = v + arg;
resolve(true);
}, 1000)
});
}
var promise = func(0);
for (var i =1; i< 10; i++){
(function(n){
promise = promise.then(()=>{
return func(n);
});
})(i);
}
答案 2 :(得分:0)
这将从fun()
开始,继续运行,同时队列中还有增量定义:
const queue = [];
const fun = (start) => {
start = start || 0
console.log('v', start)
setTimeout(() => {
if(queue.length > 0) {
const increment = queue.shift();
fun(start + increment);
}
}, 1000)
}
queue.push(2)
queue.push(3)
fun()
queue.push(4)
queue.push(5)
请注意,根据您的浏览器,可能不支持const
关键字,需要将其转换为ES5或替换为var
关键字。