Skip to content

Instantly share code, notes, and snippets.

@grabcode
Last active July 5, 2017 03:56
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 grabcode/07e8c6b1f0ad587a887285bcc22a87b0 to your computer and use it in GitHub Desktop.
Save grabcode/07e8c6b1f0ad587a887285bcc22a87b0 to your computer and use it in GitHub Desktop.
resolveAll is concurrently running promises until they all either resolve or reject. Free to customise how to handle failure.
/*
2017, still not using Promises? You missed the memo.
Promise.all lets you run a serie (iteratable list) of promises but will reject as soon as one reject.
Sometimes though, you want to try resolving all of them, and then address the rejected ones. I call that "gracefully fail".
Usage (promises is an array of promise):
// Using the default error handler
resolveAll(promises)
.then(resolved => console.log('List of my resolved promises result'))
.catch(errors => {
// By default, resolveAll rejects only if ALL promises have rejected
// errors is the list (array) of exceptions raised
console.error(errors);
});
// Customising the error handler: logging the errors
// Below a real life scenario: I want to create as many measurement as I can in my database
resolveAll(promises, resolved => {
if (rejected) {
console.error(rejected);
}
return Promise.resolve();
})
.then(measurements => {
return Measurement.bulkCreate(measurements);
});
*/
const RESOLVED = 'resolved';
const REJECTED = 'rejected';
const reflectPromise = promise => promise.then(
v => { return { v, status: RESOLVED }; },
e => { return { e, status: REJECTED }; },
);
const defaultHandleRejected = (rejected, results) => {
if (rejected.length === results.length) {
return Promise.reject(rejected);
}
return Promise.resolve();
};
const resolveAll = (promises, handleRejected = defaultHandleRejected) => {
return Promise.all(promises.map(reflectPromise))
.then(results => {
let rejected = [];
const resolved = results.reduce((memo, result) => {
if (result.status === RESOLVED) {
memo.push(result.v);
} else {
rejected.push(result.e);
}
return memo;
}, []);
return handleRejected(rejected, results)
.then(() => resolved);
});
};
export default resolveAll;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment