UNPKG

1.86 kBJavaScriptView Raw
1/** @module concurrency */
2
3/**A **Promise.all** that does not fails-fast.
4 * Given N promises will return all of them <u>independenly if they failed or not</u>.
5 * @see [Fail-fast](https://en.wikipedia.org/wiki/Fail-fast)
6 * @see [Rob-Pike](https://www.youtube.com/watch?v=f6kdp27TYZs)
7 * @see [concurrencyTest.js](https://github.com/nerac/keyu/blob/master/test/concurrencyTest.js)
8 * @argument {Array(Promise)} promises An array of all promises to be executed
9 * @returns {Array(Object)}
10 * @example
11 * await full([Promise.resolve(1), Promise.reject(2), Promise.resolve(3)])
12 * // [ { value: 1 }, { error: 2 }, { value: 3 } ]
13 * @see [concurrencyTest.js](https://github.com/nerac/keyu/blob/master/test/concurrencyTest.js)
14 * @method
15 */
16const full = promises => Promise.all(promises.map(promise => promise.then(value => ({ value })).catch(error => ({ error }))));
17
18/** Given **N promises** will return <u>the fastest non-failed one</u>.
19 * This pattern can be useful some times to reduce latency.
20 * @see [When Do Redundant Requests Reduce Latency?](https://ieeexplore.ieee.org/document/7348681)
21 * @see [Rob-Pike](https://www.youtube.com/watch?v=f6kdp27TYZs)
22 * @argument {Array(Promise)} promises An array of all promises to be executed
23 * @returns {Promise}
24 * @example
25 * await best([Promise.resolve(1),Promise.resolve(2)]) // -> 1 (assuming 1 is the first to resolve)
26 * await best([Promise.reject(1),Promise.resolve(2)]) // -> 2
27 * @see [concurrencyTest.js](https://github.com/nerac/keyu/blob/master/test/concurrencyTest.js)
28 * @method
29 */
30const best = promises =>
31 new Promise((resolve, reject, errors = []) => {
32 promises.map(promise =>
33 promise.then(resolve).catch(err => {
34 errors.push(err);
35 if (errors.length === promises.length) {
36 reject(errors);
37 }
38 })
39 );
40 });
41
42module.exports = { best, full };