Skip to content

Instantly share code, notes, and snippets.

@normancarcamo
Last active July 13, 2018 22:55
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 normancarcamo/7da789dcb9591a0ab1a69458d7720ddf to your computer and use it in GitHub Desktop.
Save normancarcamo/7da789dcb9591a0ab1a69458d7720ddf to your computer and use it in GitHub Desktop.
Get errors and results from a parallel asynchronous call
// Wrapper to get results & errors in parallel:
// Here we could override the original Promise.all method but due to this is just merely a test, we'll just leave it aside.
function promiseAll(array, combine) {
return Promise.all(array.map(p => p.catch(e => e)))
.then(values => {
if (combine) {
return values;
}
let errors = values.reduce((target, value) => {
if (value instanceof Error) {
target.push(value);
};
return target;
}, []);
if (errors.length) {
throw errors;
} else {
return values;
};
});
}
// Helper for the proof of concept:
function create({ message, time, error }) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (error) {
reject(new Error(message));
} else {
resolve(message);
}
}, time || 1000);
});
}
// Invoke (not combined):
promiseAll([
create({ message: 'OK 1!' }),
create({ message: 'OK 2!' }),
create({ message: 'NO 3!', error: true, time: 3000 }),
create({ message: 'OK 4!' }),
create({ message: 'NO 5!', error: true, time: 2000 })
])
.then(result => {
console.log('PASS:', result);
})
.catch(error => {
console.log('FAIL:', error);
})
/* output: (2 errors)
FAIL: (2) [Error: NO 3!
at setTimeout (<anonymous>:25:16), Error: NO 5!
at setTimeout (<anonymous>:25:16)]
*/
// Invoke (combined):
// Using true as second parameter we will get all the errors and results and the promise will be resolved.
// So, here we don't need a catch block.
promiseAll([
create({ message: 'OK 1!' }),
create({ message: 'OK 2!' }),
create({ message: 'NO 3!', error: true, time: 3000 }),
create({ message: 'OK 4!' }),
create({ message: 'NO 5!', error: true, time: 2000 })
], true)
.then(result => {
console.log(result);
});
/* output: (2 errors & 3 results)
["OK 1!", "OK 2!", Error: NO 3!
at setTimeout (<anonymous>:29:16), "OK 4!", Error: NO 5!
at setTimeout (<anonymous>:29:16)]
*/
// Method #3 (Tradition way) it just throw the last error found:
Promise.all([
create({ message: 'OK 1!' }),
create({ message: 'OK 2!' }),
create({ message: 'NO 3!', error: true, time: 3000 }),
create({ message: 'OK 4!' }),
create({ message: 'NO 5!', error: true, time: 2000 })
])
.then(result => {
console.log('PASS:', result);
})
.catch(error => {
console.log('FAIL:', error);
})
/* output: (fail with the last error found)
FAIL: Error: NO 5!
at setTimeout (<anonymous>:5:16)
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment