¿Cómo construir correctamente un bucle para asegurarse de que la siguiente llamada de promesa y el logger.log (res) encadenado se ejecuten sincrónicamente a través de la iteración? (azulejo)
db.getUser(email).then(function(res) { logger.log(res); }); // this is a promise
Intenté de la siguiente manera (método de http://blog.victorquinn.com/javascript-promise- while-loop )
var Promise = require('bluebird');
var promiseWhile = function(condition, action) {
var resolver = Promise.defer();
var loop = function() {
if (!condition()) return resolver.resolve();
return Promise.cast(action())
.then(loop)
.catch(resolver.reject);
};
process.nextTick(loop);
return resolver.promise;
});
var count = 0;
promiseWhile(function() {
return count < 10;
}, function() {
return new Promise(function(resolve, reject) {
db.getUser(email)
.then(function(res) {
logger.log(res);
count++;
resolve();
});
});
}).then(function() {
console.log('all done');
});
Aunque parece funcionar, no creo que garantice el orden de llamada a logger.log (res);
¿Alguna sugerencia?
javascript
node.js
promise
bluebird
user2127480
fuente
fuente
loop
función es la forma de hacer bucles sincrónicos). ¿Por qué crees que no hay garantía?while
código?Respuestas:
De hecho, lo hace. Esa declaración se ejecuta antes de la
resolve
llamada.Un montón. El más importante es el uso del antipatrón create-promise-manualmente , solo hazlo
En segundo lugar, esa
while
función podría simplificarse mucho:En tercer lugar, no usaría un
while
bucle (con una variable de cierre) sino unfor
bucle:fuente
action
tomavalue
como argumentopromiseFor
. SO no me dejaría hacer una edición tan pequeña. Gracias, es muy útil y elegante.while
bucle prueba algún estado global mientras que unfor
bucle tiene su variable de iteración (contador) vinculada al cuerpo del bucle. De hecho, he usado un enfoque más funcional que se parece más a una iteración de punto fijo que a un bucle. Verifique su código nuevamente, elvalue
parámetro es diferente..bind()
ofusca lo nuevovalue
, creo que podría optar por escribir la función para facilitar la lectura. Y lo siento si estoy siendo gordo pero sipromiseFor
ypromiseWhile
no coexistimos, ¿cómo se llama uno al otro?return …
porreturn Promise.resolve(…)
. Si necesita salvaguardas adicionales contracondition
oaction
lanzar una excepción (como laPromise.method
proporciona ), envuelva todo el cuerpo de la función en unreturn Promise.resolve().then(() => { … })
Promise.resolve().then(action).…
oPromise.resolve(action()).…
, no es necesario ajustar el valor de retorno dethen
Si realmente desea una
promiseWhen()
función general para este y otros propósitos, entonces hágalo utilizando las simplificaciones de Bergi. Sin embargo, debido a la forma en que funcionan las promesas, pasar las devoluciones de llamada de esta manera generalmente es innecesario y te obliga a atravesar pequeños aros complejos.Por lo que puedo decir, lo estás intentando:
.then()
cadena mediante recursividad.Así definido, el problema es en realidad el que se analiza en "The Collection Kerfuffle" en Promise Anti-patterns , que ofrece dos soluciones simples:
Array.prototype.map()
Array.prototype.reduce()
.El enfoque paralelo le dará (directamente) el problema que está tratando de evitar: que el orden de las respuestas es incierto. El enfoque en serie construirá la
.then()
cadena requerida , plana, sin recursividad.Llame de la siguiente manera:
Como puede ver, no hay necesidad de la var externa fea
count
o sucondition
función asociada . El límite (de 10 en la pregunta) está determinado completamente por la longitud de la matrizarrayOfEmailAddys
.fuente
Así es como lo hago con el objeto Promise estándar.
fuente
chain = chain.then(func.bind(null, "...your params here"));
ochain = chain.then(() => func("your params here"));
Dado
Necesario
Solución
fuente
async
está a punto de convertirse en una palabra reservada en JavaScript, podría agregar claridad para cambiar el nombre de esa función aquí.current
no se usa.Hay una nueva forma de resolver esto y es usando async / await.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function https://ponyfoo.com/articles/understanding-javascript-async-await
fuente
La función sugerida por Bergi es realmente agradable:
Aún así, quiero hacer una pequeña adición, que tiene sentido, cuando uso promesas:
De esta manera, el ciclo while se puede incrustar en una cadena de promesas y se resuelve con lastValue (también si la acción () nunca se ejecuta). Ver ejemplo:
fuente
Haría algo como esto:
de esta manera, dataAll es una matriz ordenada de todos los elementos a registrar. Y la operación de registro se realizará cuando se cumplan todas las promesas.
fuente
Utilice async y await (es6):
fuente
fuente
¿Qué tal este usando BlueBird ?
fuente
Aquí hay otro método (ES6 w / std Promise). Utiliza criterios de salida de tipo lodash / subrayado (return === falso). Tenga en cuenta que puede agregar fácilmente un método exitIf () en las opciones para ejecutar en doOne ().
fuente
Usar el objeto de promesa estándar y hacer que la promesa devuelva los resultados.
fuente
Primero tome la matriz de promesas (matriz de promesas) y luego resuelva estas matrices de promesas usando
Promise.all(promisearray)
.fuente