I have a ton of functions that need to run in succession, but not before the other has completed. What I need is a way to queue these functions to run only after the previou
You could use something like this:
var FunctionQueue = (function(){
var queue = [];
var add = function(fnc){
queue.push(fnc);
};
var goNext = function(){
var fnc = queue.shift();
fnc();
};
return {
add:add,
goNext:goNext
};
}());
and use it like this:
var fnc1 = function(){
window.setTimeout(function(){
alert("1 done");
FunctionQueue.goNext();
}, 1000);
};
var fnc2 = function(){
window.setTimeout(function(){
alert("2 done");
FunctionQueue.goNext();
}, 5000);
};
var fnc3 = function(){
window.setTimeout(function(){
alert("3 done");
FunctionQueue.goNext();
}, 2000);
};
FunctionQueue.add(fnc1);
FunctionQueue.add(fnc2);
FunctionQueue.add(fnc3);
FunctionQueue.goNext();
Edit after a few years:
Another way people are approaching this is to pass in a next
function that you can call to continue the chain. Like so:
var Queue = function(arr){
var index = 0;
var next = function(){
if (index >= arr.length) {return;}
arr[index++](next);
};
return next;
};
var fn1 = function(next){
console.log("I am FN1");
next();
};
var fn2 = function(next){
console.log("I am FN2");
setTimeout(next,1000);
};
var fn3 = function(next){
console.log("I am FN3");
setTimeout(next,3000);
};
var fn4 = function(next){
console.log("I am FN4");
setTimeout(next,1000);
};
Queue([fn1, fn2, fn3, fn4])();
Check out async.js - it provides a mechanism for chaining up functions so they execute asynchronously or one after another, with an excellent way to catch the results and/or errors from all the executed functions.
https://github.com/caolan/async
Why don't you do exactly as you have shown, by listing them in a covering function?
function do_1_to_5() {
Function1();
Function2();
Function3();
Function4();
Function5();
}
If your function contains AJAX calls, then you need to hook them up at the end of the callback functions that handle the AJAX calls.
You could create a Queue function:
function Queue(arr) {
var i = 0;
this.callNext = function() {
typeof arr[i] == 'function' && arr[i++]();
};
}
So if these were your functions...
function f1() {
alert(1);
}
function f2() {
alert(2);
}
function f3() {
alert(3);
}
... you just pass them (their references) inside a new Queue instance:
var queue = new Queue([f1, f2, f3]);
Then you execute callNext()
to call the functions sequentially:
queue.callNext();
queue.callNext();
queue.callNext();
Live demo: http://jsfiddle.net/CEdPS/3/
You don't need all that machinery, just put your functions in an array. Then you can loop over them.
var runThese = [
Function1,
Function2,
Function3,
Function4,
Function5
];
JavaScript is single-threaded so you're guaranteed one finishes before the next starts.
for (var i = 0; i < runThese.length; i++) {
runThese[i]();
}
Or since your functions have deterministic names, you could avoid the array altogether:
for (var i = 1; i <= 5; i++) {
window["Function" + String(i)]();
}
To make sure they run consecutively, you might return a value from each one and use that returned value in the subsequent one...
function do_1_to_5() {
r1 = Function1();
r2 = Function2(r1);
r3 = Function3(r2);
r4 = Function4(r3);
r5 = Function5(r4);
}