I have an array of Promises that I'm resolving with Promise.all(arrayOfPromises);
I go on to continue the promise chain. Looks something like this
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(); });
I want to add a catch statement to handle an individual promise in case it errors, but when I try, Promise.all
returns the first error it finds (disregards the rest), and then I can't get the data from the rest of the promises in the array (that didn't error).
I've tried doing something like ..
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(); });
But that doesn't resolve.
Thanks!
--
Edit:
What the answers below said were completely true, the code was breaking due to other reasons. In case anyone is interested, this is the solution I ended up with ...
Node Express Server Chain
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; }) };
API Call (route.async call)
return async() .then(function(result) { // dispatch a success return result; }) .catch(function(err) { // dispatch a failure and throw error throw err; });
Putting the .catch
for Promise.all
before the .then
seems to have served the purpose of catching any errors from the original promises, but then returning the entire array to the next .then
Thanks!
Promise. all is all or nothing. It resolves once all promises in the array resolve, or reject as soon as one of them rejects. In other words, it either resolves with an array of all resolved values, or rejects with a single error.
all(promises) – The function waits for all promises to resolve and returns the array of their results. If any of the given promises rejects, it becomes an error of the Promise. all() method and all other results are ignored.
The Promise. all() method is actually a method of Promise object (which is also an object under JavaScript used to handle all the asynchronous operations), that takes an array of promises(an iterable) as an input.
all to Stop Async/Await from Blocking Execution in JS. When writing asynchronous code, async/await is a powerful tool — but it comes with risks! Learn how to avoid code slowdowns in this tutorial.
Promise.all
is all or nothing. It resolves once all promises in the array resolve, or reject as soon as one of them rejects. In other words, it either resolves with an array of all resolved values, or rejects with a single error.
Some libraries have something called Promise.when
, which I understand would instead wait for all promises in the array to either resolve or reject, but I'm not familiar with it, and it's not in ES6.
Your code
I agree with others here that your fix should work. It should resolve with an array that may contain a mix of successful values and errors objects. It's unusual to pass error objects in the success-path but assuming your code is expecting them, I see no problem with it.
The only reason I can think of why it would "not resolve" is that it's failing in code you're not showing us and the reason you're not seeing any error message about this is because this promise chain is not terminated with a final catch (as far as what you're showing us anyway).
I've taken the liberty of factoring out the "existing chain" from your example and terminating the chain with a catch. This may not be right for you, but for people reading this, it's important to always either return or terminate chains, or potential errors, even coding errors, will get hidden (which is what I suspect happened here):
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 });
NEW ANSWER
const results = await Promise.all(promises.map(p => p.catch(e => e))); const validResults = results.filter(result => !(result instanceof Error));
FUTURE Promise API
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With