javascript - termine - Node.js-espera múltiples llamadas asincrónicas
promesas javascript (4)
Puedes usar el módulo async :
var states = [{"State" : "NY"},{"State" : "NJ"}];
var findLakes = function(state,callback){
db.collection(''lakes'').find(state).toArray(callback);
}
async.map(states, findLakes , function(err, results){
// do something with array of results
});
Estoy tratando de hacer múltiples consultas de MongoDB antes de renderizar una plantilla de Jade, pero no puedo entender cómo esperar hasta que se completen todas las consultas de Mongo antes de renderizar la plantilla.
exports.init = function(req, res){
var NYLakes = {};
var NJLakes = {};
var filterNY = {"State" : "NY"};
db.collection(''lakes'').find(filterNY).toArray(function(err, result) {
if (err) throw err;
NYLakes = result;
});
var filterNJ = {"State" : "NJ"};
db.collection(''lakes'').find(filterNJ).toArray(function(err, result) {
if (err) throw err;
NJLakes = result;
});
res.render(''explore/index'',
{
NYlakes: NYLakes,
NJlakes: NJLakes
}
);
};
Soy un gran fan de subrayado / lodash, por lo que usualmente uso _.after
, que crea una función que solo se ejecuta después de haber sido llamada una cierta cantidad de veces.
var finished = _.after(2, doRender);
asyncMethod1(data, function(err){
//...
finished();
});
asyncMethod2(data, function(err){
//...
finished();
})
function doRender(){
res.render(); // etc
}
Como javascript eleva la definición de funciones definidas con la function funcName()
, el código se lee de forma natural: de arriba hacia abajo.
Suponiendo que desea ejecutar las dos operaciones en paralelo en lugar de esperar a que una termine antes de comenzar la siguiente, necesitará realizar un seguimiento de cuántas operaciones se han completado en cada devolución de llamada.
En raw node.js javascript, una forma de hacerlo sería esta:
exports.init = function(req, res){
var NYLakes = null;
var NJLakes = null;
var filterNY = {"State" : "NY"};
db.collection(''lakes'').find(filterNY).toArray(function(err, result) {
if (err) throw err;
NYLakes = result;
complete();
});
var filterNJ = {"State" : "NJ"};
db.collection(''lakes'').find(filterNJ).toArray(function(err, result) {
if (err) throw err;
NJLakes = result;
complete();
});
function complete() {
if (NYLakes !== null && NJLakes !== null) {
res.render(''explore/index'', {
NYlakes: NYLakes,
NJlakes: NJLakes
});
}
}
};
Básicamente, lo que sucede aquí es que verifique al final de cada operación si todas ellas han terminado, y en ese punto terminará la operación.
Si está haciendo muchas de estas cosas, eche un vistazo a la biblioteca async como un ejemplo de herramienta para facilitar la administración de este tipo de cosas.
Wait.for https://github.com/luciotato/waitfor
usando Wait.for:
exports.init = function(req, res){
var NYLakes = {};
var NJLakes = {};
var coll = db.collection(''lakes'');
var filterNY = {"State" : "NY"};
var a = wait.forMethod(coll,''find'',filterNY);
NYLakes = wait.forMethod(a,''toArray'');
var filterNJ = {"State" : "NJ"};
var b = wait.forMethod(coll,''find'',filterNJ);
NJLakes = wait.forMethod(b,''toArray'');
res.render(''explore/index'',
{
NYlakes: NYLakes,
NJlakes: NJLakes
}
);
};
Solicitando en paralelo usando wait.for map paralelo:
exports.init = function(req, res){
var coll = db.collection(''lakes'');
//execute in parallel, wait for results
var result = wait.parallel.map(
[{coll:coll,filter:{"State" : "NY"}}
, {coll:coll,filter:{"State" : "NJ"}}]
, getData);
res.render(''explore/index'',
{
NYlakes: result[0],
NJlakes: result[1]
}
);
};
//map function
function getData(item,callback){
try{
var a = wait.forMethod(item.coll,''find'',item.filter);
var b = wait.forMethod(a,''toArray'');
callback (null, b);
} catch(err){
callback(err);
}
No estoy familiarizado con Mongo, por lo que es posible que tengas que ajustar las llamadas.