2011-02-10 10 views
5

Ho un sacco di funzioni che devono essere eseguite in successione, ma non prima che l'altra sia completata. Quello di cui ho bisogno è un modo per accodare queste funzioni affinché vengano eseguite solo dopo che la funzione precedente è stata completata con successo. Qualche idea?Coda funzione JavaScript

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

Il codice dovrebbe funzionare bene ... (se per "con successo completato" vuoi dire che la funzione restituito) –

+1

C'è roba asincrona nelle funzioni? In caso contrario, non riesco a vedere un problema. – spender

+0

La maggior parte delle mie funzioni contiene chiamate AJAX. E ognuno dipende da un successo della precedente chiamata. – user610728

risposta

0

Perché non fai esattamente come hai mostrato, elencandoli in una funzione di copertura?

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

Se la funzione contiene chiamate AJAX, allora avete bisogno di agganciarli alla fine delle funzioni di callback che gestire la chiamate AJAX.

+0

Questo è esattamente ciò che stavo facendo, inserendo la funzione successiva nel callback di successo della chiamata $ .ajax di jquery. Ho solo pensato che potesse esserci una soluzione migliore. – user610728

0

Per assicurarsi che corrono consecutivamente, si potrebbe restituire un valore da ciascuno di essi e l'uso che ha restituito il valore in quella successiva ...

function do_1_to_5() { 

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

} 
7

Si potrebbe usare qualcosa di simile:

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

e usare in questo modo:

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

Modifica dopo pochi anni: Un altro modo in cui le persone si stanno avvicinando a questo è passare una funzione next che è possibile chiamare per continuare la catena. In questo modo:

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

Si potrebbe creare una funzione coda:

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

Quindi, se queste erano le funzioni ...

function f1() { 
    alert(1); 
} 

function f2() { 
    alert(2); 
} 

function f3() { 
    alert(3); 
} 

... appena li pass (i loro riferimenti) all'interno di una nuova istanza Queue:

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

Poi si esegue callNext() per chiamare le funzioni in sequenza:

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

Demo online:http://jsfiddle.net/CEdPS/3/

0

non hai bisogno di tutto che le macchine, basta mettere le funzioni in un array. Quindi puoi passarci sopra.

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

JavaScript è a thread singolo in modo da garantirne la finitura prima dell'avvio successivo.

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

O poiché le funzioni deterministiche hanno nomi, si potrebbe evitare la matrice del tutto:

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

Non ha visto il commento che ogni funzione deve attendere qualcosa di asincrono sulla funzione precedente. Quindi questo non è quello che ti serve dopo tutto. Non è possibile rispondere correttamente alla domanda senza conoscere il contenuto delle funzioni. – jpsimons

0

Scopri async.js - fornisce un meccanismo per il concatenamento delle funzioni in modo da eseguire in modo asincrono o uno dopo un altro, con un ottimo modo per catturare i risultati e/o gli errori di tutte le funzioni eseguite.

https://github.com/caolan/async