Last active
February 13, 2019 08:19
-
-
Save emmanuelnk/510468e3d2211b827e7753cf6e2eef5c to your computer and use it in GitHub Desktop.
Handling the fast-fail behavior of Promise.all when using async/await
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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