Skip to content

Instantly share code, notes, and snippets.

@emmanuelnk
Last active February 13, 2019 08:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save emmanuelnk/510468e3d2211b827e7753cf6e2eef5c to your computer and use it in GitHub Desktop.
Save emmanuelnk/510468e3d2211b827e7753cf6e2eef5c to your computer and use it in GitHub Desktop.
Handling the fast-fail behavior of Promise.all when using async/await
// TL,DR :
// here is a wrapper for PromiseAll that handles rejection and avoids fast fail behavior
const softPromiseAll = arr => {
return Promise.all(arr.map(
promise => new Promise(
resolve => promise.then(resolve).catch(resolve)
)
)).then(results => results)
}
// Example
// here is example usage
const promiseTimed = (sec) => {
return new Promise((resolve, reject) => {
if (sec)
setTimeout(()=>{
resolve(`this promise finished after ${sec} seconds`)
}, sec * 1000)
else
reject(`this promise failed!`) // or throw new Error('unhandled exception!')
})
}
// uses regular Promise.all, no rejections, so it works
const normalPromiseAllExample = async () => {
console.time('normalPromiseAllExample')
console.log((await Promise.all([
promiseTimed(1),
promiseTimed(2),
promiseTimed(5),
promiseTimed(6),
promiseTimed(7),
])).map( result => result ))
console.timeEnd('normalPromiseAllExample')
}
// uses regular Promise.all, has rejections, so it fails fast
const normalPromiseAllWithRejectionExample = async () => {
console.time('normalPromiseAllWithRejectionExample')
console.log((await Promise.all([
promiseTimed(1),
promiseTimed(2),
promiseTimed(5),
promiseTimed(), // forces a rejection
promiseTimed(7),
])).map( result => result ))
console.timeEnd('normalPromiseAllWithRejectionExample')
}
// uses safe wrapped Promise.all, has no rejections, so it works obviously
const safePromiseAllExample = async () => {
console.time('safePromiseAllExample')
console.log((await softPromiseAll([
promiseTimed(1),
promiseTimed(2),
promiseTimed(5),
promiseTimed(6),
promiseTimed(7),
])).map( result => result) )
console.timeEnd('safePromiseAllExample')
}
// uses safe wrapped Promise.all, has a rejection, but it resolves all promises
const safePromiseAllWithRejectionExample = async () => {
console.time('safePromiseAllWithRejectionExample')
console.log((await softPromiseAll([
promiseTimed(1),
promiseTimed(2),
promiseTimed(5),
promiseTimed(), // forces a rejection
promiseTimed(7),
])).map( result => result) )
console.timeEnd('safePromiseAllWithRejectionExample')
}
// just to show performance with a large array
const safePromiseAllLargeArrayExample = async () => {
console.time('safePromiseAllLargeArrayExample')
console.log((await softPromiseAll(
Array.apply(null, Array(500)).map( i => promiseTimed(10))
)).map( result => result) )
console.timeEnd('safePromiseAllLargeArrayExample')
}
normalPromiseAllExample()
normalPromiseAllWithRejectionExample()
safePromiseAllExample()
safePromiseAllWithRejectionExample()
safePromiseAllLargeArrayExample() // to show performance with large arrays
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment