javascript: esegue un gruppo di metodi asincroni con un callback

Devo eseguire una serie di metodi asincroni (database SQLite client) e chiamare solo un callback finale.

Certo, il modo brutto è:

execAll : function(callBack) { asynch1(function() { asynch2(function() { ... asynchN(function() { callBack(); }) }) }); } 

Ma so che ci sono modi migliori per farlo. Intuitivamente rileverei quando tutte le richiamate sono state chiamate con un contatore per chiamare la callback finale.

Penso che questo sia un modello di progettazione comune, quindi se qualcuno potrebbe indicarmi la giusta direzione …

Grazie in anticipo !

questo è facile

 var callback = (function(){ var finishedCalls = 0; return function(){ if (++finishedCalls == 4){ //execute your action here } }; })(); 

Basta passare questa richiamata a tutti i tuoi metodi, e una volta che è stata chiamata 4 volte verrà eseguita.

Se si desidera utilizzare la fabbrica per questo, è ansible effettuare quanto segue

 function createCallback(limit, fn){ var finishedCalls = 0; return function(){ if (++finishedCalls == limit){ fn(); } }; } var callback = createCallback(4, function(){ alert("woot!"); }); async1(callback); async2(callback); async3(callback); async4(callback); 

Ho scritto alcune utility asincrone che potresti trovare utili, permettendoti di scrivere il tuo esempio come:

 function(callback) { async.series([ asynch1(), asynch2(), ... asynchN() ], callback); } 

Oppure, se volessi eseguirli in parallelo, come:

 function(callback) { async.parallel([ asynch1(), asynch2(), ... asynchN() ], callback); } 

Ci sono molte altre utili funzioni come la mappa asincrona / ridurre troppo:

http://caolanmcmahon.com/async.html

Spero possa aiutare!

Si dovrebbe prendere in considerazione l’utilizzo del pattern rinviato per i metodi asincroni. Puoi ottenere maggiori informazioni dalla domanda e dalle risposte di StackOverflow:

Quali sono le differenze tra Differito, Promesso e Futuro in JavaScript?

La buona risposta di jnewman in realtà era buona!

Spero che questo ti aiuti.

Le promesse possono aiutare a gestirlo. Esistono due scenari generali: parallelo e seriale. Il parallelismo può essere realizzato usando Promise.all (), il serial è più complesso – l’attività B può essere avviata solo quando l’attività A è terminata. Ecco un campione di ossa nude:

 // returns a promise that resolves as the task is done const wrap = (fn, delay) => new Promise(resolve => setTimeout(_ => resolve(fn()), delay)); const task = (fn, delay) => delay ? wrap(fn, delay) : Promise.resolve(fn()); // given a list of promises, execute them one by one. const sequence = async l => l.reduce(async (a, b) => [].concat(await a, await b)); const tasks = [ task(_ => console.log("hello world")), task(_ => console.log("hello future"), 1000) ]; sequence(tasks).then(_ => console.log("all done")); 

Potrebbe essere necessaria una traduzione ES6 / 7 per farlo funzionare nei browser o versioni di nodes precedenti.