Det eksploderede, fordi du ikke venter på, at et asynkront opkald skal fuldføres, før du går videre til næste iteration. Hvad dette betyder er, at du bygger en "stak" af uløste operationer, indtil dette forårsager et problem. Hvad er navnet på denne side igen? Får du billedet?
Så dette er ikke den bedste måde at fortsætte med "Bulk"
indsættelser. Heldigvis har den underliggende MongoDB-driver allerede tænkt over dette, bortset fra det tidligere nævnte tilbagekaldsproblem. Der er faktisk en "Bulk API"
tilgængelig for at gøre dette meget bedre. Og forudsat at du allerede har trukket den oprindelige driver som db
objekt. Men jeg foretrækker bare at bruge .collection
accessor fra modellen og "async"
modul for at gøre alt klart:
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" ;
}
);
Forskellen der er at bruge både "asynkrone" tilbagekaldsmetoder ved afslutning snarere end blot at opbygge en stak, men også at bruge "Bulk Operations API" for at afbøde de asynkrone skrivekald ved at indsende alt i batchopdateringserklæringer på 1000 poster.
Dette "opbygger ikke kun en stak" af funktionsudførelse som din egen eksempelkode, men udfører også effektive "wire" transaktioner ved ikke at sende alt i individuelle erklæringer, men snarere opdeles i håndterbare "batches" for serverforpligtelse .