From 47f9d9c9310b42ac7a94ee3ee9f7f42288205747 Mon Sep 17 00:00:00 2001 From: Shaban-Eissa Date: Tue, 4 Jun 2024 21:14:02 +0300 Subject: [PATCH] feat: implement Promise.all() --- 32.implement-Promise.all.md | 102 ++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 32.implement-Promise.all.md diff --git a/32.implement-Promise.all.md b/32.implement-Promise.all.md new file mode 100644 index 0000000..a48427e --- /dev/null +++ b/32.implement-Promise.all.md @@ -0,0 +1,102 @@ +# 32. implement `Promise.all()` +Promise.all is a method in JavaScript used to handle multiple promises concurrently. It takes an iterable (such as an array) of promises and returns a single promise. This returned promise resolves when all the promises in the iterable have resolved, or rejects if any of the promises in the iterable reject. + +### Key Features of `Promise.all` + +1. **Concurrent Execution**: + + * `Promise.all` runs multiple promises in parallel. + * It waits for all the promises to settle (either resolved or rejected). +2. **Resolved Value**: + + * When all promises resolve, `Promise.all` resolves with an array of their results, maintaining the order of the original promises. + * Example: `Promise.all([promise1, promise2]).then((values) => { console.log(values); });` + * If `promise1` resolves to `value1` and `promise2` resolves to `value2`, the output will be `[value1, value2]`. +3. **Rejection Handling**: + + * If any promise in the iterable rejects, `Promise.all` immediately rejects with the reason of the first promise that rejected. + * Example: `Promise.all([promise1, promise2]).catch((error) => { console.log(error); });` + * If `promise1` rejects with an `error1`, `Promise.all` will reject with `error1`. + + +### Problem + +https://bigfrontend.dev/problem/implement-Promise-all + +# + +### Problem Description + +> The Promise.all() method takes an iterable of promises as an input, and returns a single Promise that resolves to an array of the results of the input promises + +source - [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all) + +Could you write your own `all()` ? which should works the same as `Promise.all()` + +# + +### Solution + +```js +/** + * @param {Array} promises - notice input might have non-Promises + * @return {Promise} + */ +function all(promises) { + if (promises.length === 0) { + return Promise.resolve([]); + } + + const results = Array(promises.length); + let count = 0; + + return new Promise((resolve, reject) => { + promises.forEach((promise, i) => { + if (!(promise instanceof Promise)) { + promise = Promise.resolve(promise); + } + + promise + .then((res) => { + results[i] = res; + count++; + + if (count === promises.length) { + resolve(results); + } + }) + .catch((err) => { + reject(err); + }); + }); + }); +} +``` + +### Example Usage + +```javascript +const promise1 = Promise.resolve(3); +const promise2 = new Promise((resolve, reject) => setTimeout(resolve, 100, 'foo')); +const promise3 = fetch('https://api.example.com/data'); + +Promise.all([promise1, promise2, promise3]) + .then((values) => { + console.log(values); // [3, 'foo', Response object from fetch] + }) + .catch((error) => { + console.error('One of the promises failed:', error); + }); +``` + +### Use Cases + +* **Aggregating Results**: When you need to wait for multiple asynchronous operations to complete before proceeding, such as fetching data from multiple sources. +* **Parallel Execution**: When operations do not depend on each other and can be executed in parallel for efficiency. + +### Important Notes + +* If the iterable passed to `Promise.all` is empty, it returns a promise that resolves to an empty array. +* The order of results in the resolved array corresponds to the order of the promises passed to `Promise.all`. + +By leveraging `Promise.all`, developers can handle multiple asynchronous operations efficiently, ensuring that subsequent code execution waits until all specified promises have been settled. \ No newline at end of file