Tengo una serie de Promises que estoy resolviendo con Promise.all(arrayOfPromises);
Sigo adelante para continuar la cadena de promesas. se parece a esto
existingPromiseChain = existingPromiseChain.then(function() { var arrayOfPromises = state.routes.map(function(route){ return route.handler.promiseHandler(); }); return Promise.all(arrayOfPromises) }); existingPromiseChain = existingPromiseChain.then(function(arrayResolved) { // do stuff with my array of resolved promises, eventually ending with a res.send(); }); Quiero agregar una instrucción catch para manejar una promesa individual en caso de que se produzca un error, pero cuando lo intento, Promise.all devuelve el primer error que encuentra (ignora el resto), y luego no puedo obtener los datos del resto de las promesas en la matriz (que no dieron error).
He intentado hacer algo como ..
existingPromiseChain = existingPromiseChain.then(function() { var arrayOfPromises = state.routes.map(function(route){ return route.handler.promiseHandler() .then(function(data) { return data; }) .catch(function(err) { return err }); }); return Promise.all(arrayOfPromises) }); existingPromiseChain = existingPromiseChain.then(function(arrayResolved) { // do stuff with my array of resolved promises, eventually ending with a res.send(); });Pero eso no resuelve.
¡Gracias!
--
Editar:
Lo que decían las respuestas a continuación era completamente cierto, el código se estaba rompiendo debido a otras razones. En caso de que alguien esté interesado, esta es la solución que terminé con ...
Cadena de servidores Node Express
serverSidePromiseChain .then(function(AppRouter) { var arrayOfPromises = state.routes.map(function(route) { return route.async(); }); Promise.all(arrayOfPromises) .catch(function(err) { // log that I have an error, return the entire array; console.log('A promise failed to resolve', err); return arrayOfPromises; }) .then(function(arrayOfPromises) { // full array of resolved promises; }) };Llamada API (llamada route.async)
return async() .then(function(result) { // dispatch a success return result; }) .catch(function(err) { // dispatch a failure and throw error throw err; }); Poner .catch para Promise.all antes de .then parece haber servido para detectar cualquier error de las promesas originales, pero luego devolver la matriz completa al siguiente .then
¡Gracias!
Promise.all es todo o nada. Se resuelve una vez que se resuelven todas las promesas en la matriz, o se rechaza tan pronto como se rechaza una de ellas. En otras palabras, se resuelve con una matriz de todos los valores resueltos o se rechaza con un solo error.
Algunas bibliotecas tienen algo llamado Promise.when , que entiendo esperaría a que todas las promesas en la matriz se resuelvan o rechacen, pero no estoy familiarizado con eso, y no está en ES6.
Tu codigo
Estoy de acuerdo con otros aquí en que su solución debería funcionar. Debería resolverse con una matriz que puede contener una combinación de valores correctos y objetos de errores. Es inusual pasar objetos de error en la ruta de éxito, pero suponiendo que su código los esté esperando, no veo ningún problema con eso.
La única razón por la que puedo pensar por qué "no se resolvería" es que está fallando en el código que no nos está mostrando y la razón por la que no ve ningún mensaje de error al respecto es porque esta cadena de promesa no termina con un final catch (en cuanto a lo que nos estás mostrando de todos modos).
Me he tomado la libertad de factorizar la "cadena existente" de su ejemplo y terminar la cadena con un retén. Puede que esto no sea adecuado para usted, pero para las personas que leen esto, es importante siempre devolver o terminar las cadenas, o los errores potenciales, incluso los errores de codificación, se ocultarán (que es lo que sospecho que sucedió aquí):
Promise.all(state.routes.map(function(route) { return route.handler.promiseHandler().catch(function(err) { return err; }); })) .then(function(arrayOfValuesOrErrors) { // handling of my array containing values and/or errors. }) .catch(function(err) { console.log(err.message); // some coding error in handling happened });NUEVA RESPUESTA
const results = await Promise.all(promises.map(p => p.catch(e => e))); const validResults = results.filter(result => !(result instanceof Error));API de promesa FUTURA
ES2020 presenta un nuevo método para el tipo Promise : Promise.allSettled() .
Promise.allSettledle da una señal cuando se liquidan todas las promesas de entrada, lo que significa que se cumplen o se rechazan. Esto es útil en los casos en los que no le importa el estado de la promesa, solo desea saber cuándo se realiza el trabajo, independientemente de si se realizó correctamente.
(async function() { const promises = [ fetch('//api.stackexchange.com/2.2'), // succeeds fetch('/this-will-fail') // fails ]; const result = await Promise.allSettled(promises); console.log(result.map(promise => promise.status)); // ['fulfilled', 'rejected'] })();Obtenga más información en la publicación del blog v8 .