JavaScript函数队列

时间:2011-02-10 02:26:55

标签: javascript jquery javascript-events

我有很多需要连续运行的功能,但是在其他功能完成之前没有。我需要的是一种方法,将这些函数排队,只有在上一个函数成功完成后才能运行。任何想法?

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

6 个答案:

答案 0 :(得分:7)

您可以使用以下内容:

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

并像这样使用它:

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

几年后编辑: 人们接近这个的另一种方式是传入一个next函数,你可以调用它继续链。像这样:

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

答案 1 :(得分:5)

您可以创建一个队列功能:

function Queue(arr) {
    var i = 0;
    this.callNext = function() { 
        typeof arr[i] == 'function' && arr[i++]();
    };
}

所以如果这些是你的功能......

function f1() {
    alert(1);   
}

function f2() {
    alert(2);   
}

function f3() {
    alert(3);   
}

...您只需将它们(它们的引用)传递到新的Queue实例中:

var queue = new Queue([f1, f2, f3]);

然后执行callNext()按顺序调用函数:

queue.callNext();
queue.callNext();
queue.callNext();

现场演示: http://jsfiddle.net/CEdPS/3/

答案 2 :(得分:0)

为什么不按照你所示的方式完成,将它们列在封面功能中?

function do_1_to_5() {
    Function1(); 
    Function2(); 
    Function3(); 
    Function4(); 
    Function5();
}

如果你的函数包含AJAX调用,那么你需要在处理AJAX调用的回调函数的末尾挂钩它们。

答案 3 :(得分:0)

为了确保它们连续运行,您可以从每个值中返回一个值,并在后续的值中使用该返回值...

function do_1_to_5() {

    r1 = Function1(); 
    r2 = Function2(r1); 
    r3 = Function3(r2); 
    r4 = Function4(r3); 
    r5 = Function5(r4);

}

答案 4 :(得分:0)

你不需要所有的机器,只需将你的功能放在一个数组中。然后你可以循环它们。

var runThese = [
    Function1,
    Function2, 
    Function3,
    Function4,
    Function5
];

JavaScript是单线程的,因此您可以确保在下一次启动之前完成。

for (var i = 0; i < runThese.length; i++) {
    runThese[i]();
}

或者由于您的函数具有确定性名称,因此您可以完全避免使用该数组:

for (var i = 1; i <= 5; i++) {
    window["Function" + String(i)]();
}

答案 5 :(得分:0)

查看async.js - 它提供了一种链接函数的机制,使它们可以异步或一个接一个地执行,并且可以很好地捕获所有已执行函数的结果和/或错误。

https://github.com/caolan/async