Sent out once every month. No spam.
Let’s say we want many promises to execute in parallel and wait until all of them are resolved. Then Promise.all is the right candidate which takes an array of promises and returns a new promise.
Let's understand how Promise.all works.
Promise.all immediately rejects, completely ignoring about the other ones on the list.We are going to see an example of Promise.all and then we will implement it.
/* A simple function to sleep for certain time and then resolve it */
var sleep = (delay) => new Promise((resolve) => setTimeout(resolve, delay));
// Async function
var asyncFunz = async () => {
await sleep(2000); // await method will wait for 2 seconds and return below string
return 'Executed after 2 seconds';
};
/* Fetch user information */
var promise2 = fetch(`https://reqres.in/api/user/1`).then((res) => res.json());
/* A simple function which add's two numbers and return it */
var sum = (a, b) => a + b;
/* Adding above methods and some more to Promise.all method */
var myPromises = Promise.all([asyncFunz(), promise2, sum(1, 2), undefined, null, 1]);
/* Attaching .then, .catch methods to handle Promise.all */
myPromises.then((res) => console.log('resolved: ', res)).catch((err) => console.log('rejected: ', err));
// Above Promise.all resolves and log the result (Below line for result)
// resolved: ["Executed after 2 seconds", {data: {...}}, 3, undefined, null, 1]
In the above example, asyncFunz, promise2 are actual async functions and the rest of items in the array are a normal Function, Undefined, Null and 1.
From above example we can understand that Promise.all method accepts both async and non-async items, functions, variables etc,.
To write our custom promise.all(), we are going follow 3 steps.
promisesArr.Array) & counter (Type: Number).result variable is to store the result of items in promisesArr.counter variable to keep the count of how many items resolved so far in promisesArr.Promise object to resolve/reject and return it (More info on step 2)./* Promise.all() custom function */
function promiseAll(promisesArr) {
/* To keep the result of resolved promises */
var result = Array(promisesArr.length);
/* To keep track of how many promise got resolved */
var counter = 0;
/* To resolve/reject based on promisesArr items */
return new Promise((resolve, reject) => {});
}
new Promise() object so we can either catch or resolve the items at each iteration.Promise.resolve() method to handle both promise & non-promise items..then() & .catch() chaining methods to Promise.resolve() method to handle when the items settles in each iteration.function promiseAll(promisesArr) {
/* To keep the result of resolved promises */
var result = Array(promisesArr.length);
/* To keep track of how many promise got resolved */
var counter = 0;
/* To resolve/reject based on promisesArr items */
return new Promise((resolve, reject) => {
// Iterating the given promises array
promisesArr.forEach((promise, index) => {
// To handle both promise & non-promise in each iteration
Promise.resolve(promise)
.then((item) => {
// Store the result
})
.catch((err) => {
// If there is an error, reject it immediately
});
});
});
}
Promise.resolve() resolves, increment the counter.result variable in the respective index. So that we can maintain the order of result.counter is equal to promisesArr's length, then resolve the promise.promiseArr is rejected, then discard result and reject the outer promise.function promiseAll(promisesArr) {
/* To keep the result of resolved promises */
var result = Array(promisesArr.length);
/* To keep track of how many promise got resolved */
var counter = 0;
/* To resolve/reject based on promisesArr items */
return new Promise((resolve, reject) => {
// Iterating the given promises array
promisesArr.forEach((promise, index) => {
// We need to resolve each item in promises so that even if there is non-promise item we can handle it
Promise.resolve(promise)
.then((item) => {
counter += 1; // Update the counter
result[index] = item; // Store the result in the same order as given
/* If counter is equal to promises.length then all promises are fulfilled */
if (counter === promisesArr.length) {
resolve(result); // All promises resolved so resolve outer promise
}
})
.catch((err) => {
reject(err); // If there is an error, reject the outer promise immediately
});
});
});
}
Above piece of code may not be same as how browser vendors would have implemented Promise.all() method, but you get the idea right how it works?.
I hope this post was useful and we all have learned something new. See you in my next post. My next post will be about how to write custom spread operator and how it works. If you are not subscribed, subscribe below :D