Tuesday, 21 February, 2017 UTC


Summary

Promises have been an incredible addition to JavaScript; they save us callback hell, make coding async more maintainable, and and allow us to keep track of multiple async processes at a time.  Promise.all comes to mind, allowing us to react when multiple promises have been resolved.  Unfortunately Promise.all only resolves when all promises are resolved, so if any of the promises fail, the catch is called instead of then:
Promise.all([
    Promise.resolve(1),
    Promise.reject(0)
])
.then(() => { console.log('resolved!'); })
.catch(() => { console.log('failed!') });
// >> failed!
This is a problem if you want the same functionality to be executed regardless of if any promise in the array is rejected.  You could provide the same function to then and catch but that could lead to maintenance issues and occasional “WTF IS THIS?!” comments from other engineers.
So what should we do when we want Promise.all to trigger functionality regardless of any rejections?  Jake Archibald has the answer:
Promise.all(promises.map(p => p.catch(() => undefined)));
Each promise’s catch callback returns undefined which allows the promise’s failure to be handled as success. To prove it works, consider this snippet:
Promise.all([
    // Resolves
    Promise.resolve(1), 
    // Rejects after 2 seconds
    (() => new Promise((resolve, reject) => { setTimeout(() => reject(1), 2000) }))()
].map(p => p.catch(() => undefined))).then(() => console.log('done!'));

// >> done!
Despite the second promise being rejected, the Promise.all then is called! In the future we’ll be able to use Promise.prototype.finally to more easily handle success and failure.
Thank you to Jake for this awesome trick!
The post Promise.all for Rejections and Resolves appeared first on David Walsh Blog.