JavaScript Function Queue

前端 未结 6 2029
小蘑菇
小蘑菇 2021-01-18 16:40

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

相关标签:
6条回答
  • 2021-01-18 16:59

    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])();
    
    0 讨论(0)
  • 2021-01-18 17:07

    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

    0 讨论(0)
  • 2021-01-18 17:08

    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.

    0 讨论(0)
  • 2021-01-18 17:10

    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/

    0 讨论(0)
  • 2021-01-18 17:13

    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)]();
    }
    
    0 讨论(0)
  • 2021-01-18 17:17

    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);
    
    }
    
    0 讨论(0)
提交回复
热议问题