Il a explosé parce que vous n'attendez pas qu'un appel asynchrone se termine avant de passer à l'itération suivante. Cela signifie que vous construisez une "pile" d'opérations non résolues jusqu'à ce que cela pose un problème. C'est quoi le nom de ce site déjà ? Vous avez la photo ?
Ce n'est donc pas la meilleure façon de procéder avec "Bulk"
insertions. Heureusement, le pilote MongoDB sous-jacent a déjà pensé à cela, mis à part le problème de rappel mentionné précédemment. Il existe en fait une "Bulk API"
disponible pour rendre tout cela beaucoup mieux. Et en supposant que vous avez déjà extrait le pilote natif en tant que db
objet. Mais je préfère simplement utiliser le .collection
accesseur du modèle, et le "async"
module pour que tout soit clair :
var bulk = Model.collection.initializeOrderedBulkOp();
var counter = 0;
async.whilst(
// Iterator condition
function() { return count < 1000000 },
// Do this in the iterator
function(callback) {
counter++;
var model = buildModel(counter);
bulk.insert(model);
if ( counter % 1000 == 0 ) {
bulk.execute(function(err,result) {
bulk = Model.collection.initializeOrderedBulkOp();
callback(err);
});
} else {
callback();
}
},
// When all is done
function(err) {
if ( counter % 1000 != 0 )
bulk.execute(function(err,result) {
console.log( "inserted some more" );
});
console.log( "I'm finished now" ;
}
);
La différence est d'utiliser les deux méthodes de rappel "asynchrones" à la fin plutôt que de simplement créer une pile, mais également d'utiliser "l'API d'opérations en bloc" afin d'atténuer les appels d'écriture asynchrones en soumettant tout dans des instructions de mise à jour par lots de 1000 entrées. /P>
Cela non seulement ne "construit pas une pile" d'exécution de fonction comme votre propre exemple de code, mais effectue également des transactions "filaires" efficaces en n'envoyant pas tout dans des instructions individuelles, mais plutôt en se divisant en "lots" gérables pour l'engagement du serveur .