Array.forEach
non fornisce questa gentilezza (oh se lo fosse) ma ci sono diversi modi per realizzare ciò che vuoi:
Utilizzando un semplice contatore
function callback () { console.log('all done'); }
var itemsProcessed = 0;
[1, 2, 3].forEach((item, index, array) => {
asyncFunction(item, () => {
itemsProcessed++;
if(itemsProcessed === array.length) {
callback();
}
});
});
(grazie a @vanuan e altri) Questo approccio garantisce che tutti gli articoli vengano elaborati prima di invocare il callback "completato". È necessario utilizzare un contatore che viene aggiornato nel callback. A seconda del valore del parametro indice non fornisce la stessa garanzia, poiché l'ordine di restituzione delle operazioni asincrone non è garantito.
Utilizzo delle promesse ES6
(una libreria promessa può essere utilizzata per browser meno recenti):
Elaborare tutte le richieste garantendo l'esecuzione sincrona (ad es. 1, quindi 2 e 3)
function asyncFunction (item, cb) {
setTimeout(() => {
console.log('done with', item);
cb();
}, 100);
}
let requests = [1, 2, 3].reduce((promiseChain, item) => {
return promiseChain.then(() => new Promise((resolve) => {
asyncFunction(item, resolve);
}));
}, Promise.resolve());
requests.then(() => console.log('done'))
Elabora tutte le richieste asincrone senza esecuzione "sincrona" (2 possono terminare più velocemente di 1)
let requests = [1,2,3].map((item) => {
return new Promise((resolve) => {
asyncFunction(item, resolve);
});
})
Promise.all(requests).then(() => console.log('done'));
Utilizzando una libreria asincrona
Esistono altre librerie asincrone, la più popolare è Async , che fornisce meccanismi per esprimere ciò che desideri.
modificare
Il corpo della domanda è stato modificato per rimuovere il codice di esempio precedentemente sincrono, quindi ho aggiornato la mia risposta per chiarire. L'esempio originale utilizzava un codice simile sincrono per modellare il comportamento asincrono, quindi si applicava quanto segue:
array.forEach
è sincrono e così è res.write
, quindi puoi semplicemente mettere il callback dopo la tua chiamata per foreach:
posts.foreach(function(v, i) {
res.write(v + ". index " + i);
});
res.end();
forEach
metodo array standard avessedone
parametri diallDone
callback e callback!