Promessas em um loop for, faça algo quando terminar
Pergunta
Basicamente, estou tentando descobrir uma maneira de fazer um monte de consultas em um loop for e depois fazer algo quando todas forem concluídas.
Consegui que funcionasse, mas apenas porque usei essa ótima biblioteca que envolve todo o mongodb com promessas.
var mongo = require('mongod')
var db = mongo('mongodb://localhost/builder', ['block''])
var block_ids = ['538d097bbb12479d0e9f70ab', '538ddc7d06c1f0fe296178b1'];
var prom = null;
var blocks = [];
for (i in block_ids) {
var block_id = block_ids[i];
prom = db.block.findOne({_id:db.ObjectId(block_id)})
.then(function(results) {
blocks.push(results);
})
}
prom.done(function() {
console.dir(blocks)
console.log("DONE! " + blocks.length)
})
Minha pergunta é esta.Como diabos você pode fazer algo assim SEM promessas?Parece que seria tão difícil!
Solução
Estúpido para loops
var mongo = require('mongod')
var db = mongo('mongodb://localhost/builder', ['block''])
var block_ids = ['538d097bbb12479d0e9f70ab', '538ddc7d06c1f0fe296178b1'];
Q(block_ids.map(function(block_id) {
return db.block.findOne({_id:db.ObjectId(block_id)});
})).all().done(function(blocks) {
console.dir(blocks)
console.log("DONE! " + blocks.length)
});
Consegui que funcionasse, mas apenas porque usei essa ótima biblioteca que envolve todo o mongodb com promessas.
Em bluebird você poderia ter acabado de fazer promisifyAll(require("mongodb"))
em vez de esperar que alguém faça um módulo.
Outras dicas
Você poderia simplesmente usar uma variável simples para contar o número de respostas assim:
var responses = 0;
var blocks = [];
for(var i=0; i<block_ids.length; i++) {
var block_id = block_ids[i];
db.block.findOne({_id:db.ObjectId(block_id)}, function (err, result) {
if(err) {
console.log(err);
}
responses++;
blocks.push[result];
if (responses === block_ids.length-1) {
console.log('all find queries have responded');
// do whatever
}
}
}