Вы можете просто использовать массив.
Обратите внимание, что вывод моего кода немного отличается от вашего - я не получаю «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
EDIT
Вот, возможно, лучший вариант, который имеет дополнительное преимущество, что он будет работать должным образом, независимо от того, когда все помещён. В приведенном выше коде вам нужно вручную запускать что-то, и как только очередь будет исчерпана, ничто позднее не будет добавлено. В приведенном ниже 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
Посмотрите на библиотеку асинхронным. Он делает это для вас https://github.com/caolan/async. В частности, функция «series (...)» – bhspencer
'fun()' ничего не возвращает, чего вы ожидаете поставить в очередь? – Barmar
@Barmar Я намерен поставить там довольно сложные функции с асинхронными вызовами. Мне нужно иметь способ сказать, что «эта функция закончена, проверьте, есть ли следующая» в каждой из функций в очереди. – stkvtflw