JavaScript Function Queue

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 previous function was successfully completed. Any Ideas?

Function1();
Function2();
Function3();
Function4();
Function5();

Answers:

Answer

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])();
Answer

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/

Answer

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.

Answer

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);

}
Answer

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)]();
}
Answer

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

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us Javascript

©2020 All rights reserved.