Ele explodiu porque você não está esperando que uma chamada assíncrona seja concluída antes de passar para a próxima iteração. O que isso significa é que você está construindo uma "pilha" de operações não resolvidas até que isso cause um problema. Qual é o nome deste site novamente? Obter a imagem?
Portanto, esta não é a melhor maneira de prosseguir com "Bulk" inserções. Felizmente, o driver MongoDB subjacente já pensou nisso, além do problema de retorno de chamada mencionado anteriormente. Na verdade, existe uma "API em massa" disponível para tornar isso muito melhor. E supondo que você já puxou o driver nativo como o
db
objeto. Mas eu prefiro usar apenas o .collection
acessador do modelo e o "async"
módulo para deixar tudo claro: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" ;
}
);
A diferença é usar os dois métodos de retorno de chamada "assíncronos" na conclusão, em vez de apenas construir uma pilha, mas também empregar a "API de operações em massa" para mitigar as chamadas de gravação assíncrona enviando tudo em instruções de atualização em lote de 1.000 entradas.
Isso não apenas não "cria uma pilha" de execução de funções como seu próprio código de exemplo, mas também executa transações "wire" eficientes, não enviando tudo em instruções individuais, mas dividindo-se em "lotes" gerenciáveis para comprometimento do servidor .