/ / node.js malinterpretado diferido - node.js, promesa, diferido, q

malentendido diferido de node.js - node.js, promise, deferred, q

Estoy aprendiendo q.js y tratando de consultar 3 colecciones simultáneamente con su ayuda (evitando el infierno de devolución de llamada):

var Q = require("q")
var deferred = Q.defer();

usuarios () es un contenedor de db.collection.find ()

var users = function (){
Auth.listUsers({role:"user"}, call)
return deferred.promise
}

llamada() Es una taquigrafía para exportar promesas.

var call = function (err,data){
if (err) {
deferred.reject(err);
} else {
deferred.resolve(data);
}
}

lazo() es el bucle principal, que obtiene el cursor y los bucles a través de las entradas

var loop = function (result) {
var list = []
var promises = [];
result.each(function (err,data){
if (err) {
deferred.reject(err);
} else {
deferred.resolve(data);
promises.push(deferred.promise)
console.log("promises_:", promises) // <- internal
}
})
console.log("promises:", promises) // <- external
return Q.all(promises)
}

código:

users()
.then(loop)
.then(function(ful){
console.log("ful:", ful);  // <- here should come the queries to other collections
})

Resultado del registro de la consola al final:

promises: []    //external is empty
ful: []
promises_: [ [object Object] ]  // internal is being filled
promises_: [ [object Object], [object Object] ]

Como se puede ver, la devolución de llamada de .each Se ejecuta más tarde que empujar promesas a la matriz. Creo que se puede hacer usando result.toArray() en lugar de .each, pero ¿cómo se puede hacer con la ayuda de .each ¿lazo?

el resultado es un cursor, devuelto por el controlador mongodb después de la llamada db.collection.find () (http://mongodb.github.io/node-mongodb-native/api-generated/collection.html#find)

Respuestas

1 para la respuesta № 1
var deferred = Q.defer();
…
deferred.resolve(…);
…
deferred.resolve(…);

call() Es una taquigrafía para exportar promesas.

¡Eso no funcionará! Necesita crear un nuevo aplazado para cada promesa que desee. Sin embargo tu no debería usar Deferreds de todos modos! En su lugar, utilice el muchos Funciones de ayuda de devolución de llamada de nodo.


Como puedes ver, la devolución de llamada de.cada uno se ejecuta más tarde de empujar promesas a la matriz. Creo que se puede hacer usando result.toArray () en lugar de .each, pero ¿cómo se puede hacer con la ayuda de .each loop?

No puede, a menos que sepa de antemano con qué frecuencia each Se llamará y cuántas promesas habrá que crear. Q.all es un poco inútil aquí, ya que las promesas no se crean a la vez y ejecutan sus tareas en paralelo, en cambio, son una corriente.

Realmente deberias usar toArray Aquí, para obtener una única devolución de llamada con la que resuelva la promesa.

Bueno, hay una manera, pero es fea y menos eficiente que toArray. Puede tener un aplazado que siempre esperará, y solo se resuelve con una promesa para el resto de la transmisión.

function loop(result) {
var deferred = Q.defer();
result.each(function (err,data){
if (err) {
deferred.reject(err);
} else if (data == null) {
deferred.resolve([]); // end of the stream
} else {
var nextDeferred = Q.defer();
deferred.resolve(nextDeferred.promise.then(function(rest) {
return [data].concat(rest);
}));
deferred = nextDeferred;
}
})
return deferred.promise;
}