Tengo una estructura similar a una matriz que expone métodos asincrónicos. Las llamadas al método asíncrono devuelven estructuras de matriz que, a su vez, exponen más métodos asíncronos. Estoy creando otro objeto JSON para almacenar valores obtenidos de esta estructura, por lo que debo tener cuidado al realizar un seguimiento de las referencias en las devoluciones de llamada.
He codificado una solución de fuerza bruta, pero me gustaría aprender una solución más idiomática o limpia.
- El patrón debe ser repetible para n niveles de anidamiento.
- Necesito usar promise.all o alguna técnica similar para determinar cuándo resolver la rutina adjunta.
- No todos los elementos implicarán necesariamente realizar una llamada asíncrona. Entonces, en una promesa anidada, no puedo simplemente hacer asignaciones a los elementos de mi matriz JSON en función de index. Sin embargo, necesito usar algo como promise.all en el forEach anidado para asegurarme de que todas las asignaciones de propiedades se hayan realizado antes de resolver la rutina adjunta.
- Estoy usando la biblioteca de promesa bluebird pero esto no es un requisito
Aquí hay un código parcial:
var jsonItems = [];
items.forEach(function(item){
var jsonItem = {};
jsonItem.name = item.name;
item.getThings().then(function(things){
// or Promise.all(allItemGetThingCalls, function(things){
things.forEach(function(thing, index){
jsonItems[index].thingName = thing.name;
if(thing.type === 'file'){
thing.getFile().then(function(file){ //or promise.all?
jsonItems[index].filesize = file.getSize();
javascript
node.js
asynchronous
promise
usuario3205931
fuente
fuente
Promise.map
(concurrente) yPromise.each
(secuencial) en este caso, también tenga en cuenta quePromise.defer
está obsoleto: el código en mi respuesta muestra cómo evitarlo devolviendo promesas. Las promesas tienen que ver con los valores de retorno.Respuestas:
Es bastante sencillo con algunas reglas simples:
then
, devuélvala ; cualquier promesa que no devuelva no se esperará afuera..all
ellas , de esa manera, espera todas las promesas y no se silencia ningún error de ninguna de ellas.then
s, normalmente puede volver en el medio ; lasthen
cadenas suelen tener como máximo 1 nivel de profundidad.Y algunos consejos:
.map
que confor/push
- si está mapeando valores con una función, lemap
permite expresar de manera concisa la noción de aplicar acciones una por una y agregar los resultados.Promise.all
que ejecutar las cosas una tras otra, cada una esperando antes de la siguiente.Ok, comencemos:
fuente
Aquí hay un ejemplo simple usando reducir. Se ejecuta en serie, mantiene el orden de inserción y no requiere Bluebird.
Y utilícelo así:
Nos ha resultado útil enviar un contexto opcional en bucle. El contexto es opcional y compartido por todas las iteraciones.
Su función de promesa se vería así:
fuente
Pasé por la misma situación. Resolví usando dos Promise.All ().
Creo que fue una solución realmente buena, así que la publiqué en npm: https://www.npmjs.com/package/promise-foreach
Creo que tu código será algo como esto.
fuente
Solo para agregar a la solución presentada, en mi caso, quería obtener varios datos de Firebase para obtener una lista de productos. Así es como lo hice:
fuente