Deep dive into promise.all polyfill in javascript will help to understand the working of parallel promise calls using Promise.all and its implementation to handle parallel async API calls.
Anuj Sharma
Last Updated Sep 18, 2025
Promise.all is an important static method as part of Promise since it enables the parallel or simultaneous calling of multiple promises. This is a very common case in web development to call the multiple promises in parallel to achieve performance gain and in this case Promise.all is quite useful.
Going through the implementation of Promise.all polyfill will helps to understand the Promise.all behaviour in different use-case and its overall internal working. Let's dive into this.
Promise.all() is a static method of the Promise constructor function (a.k.a. class), which can be invoked directly using the Promise. all() method takes an iterable of promises as input and returns a single promise.
Promise.all(<Iterable of promises>)
Promise.all([]) // Iterable of promise can be blank
Here is how a static Promise.all(<Iterater of Promises>) function call works with an example.
In case, when all the promises which are part of the array(iterable) are fulfilled, and then a single promise is fulfilled containing an array of the fulfilment values of respective promises and returned by Promise.all(<Iterable of Promises>). It returns [] asynchronously when an empty array is passed.
// Case 1: When all promises get resolved
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Promise1: Resolved after 1sec!");
}, 1000);
});
const p2 = Promise.resolve("Promise2: Promise resolved immediately !!");
const p3 = 'Promise3: Converted to Promise';
Promise.all([p1, p2, p3])
.then((result) => {
console.log("result all ->", result);
})
.catch((error) => {
console.log("Error all ->", error);
});
// Output
'result all ->' [
'Promise1: Resolved after 1sec!',
'Promise2: Promise resolved immediately !!',
'Promise3: Converted to Promise'
]
It returns the first rejection reason if any input promises are rejected and no execution of the other promises if any.
// Case 2: One of the promises got rejected or throw an Error
const p1 = Promise.resolve("Promise1: Promise resolved immediately !!");
const p2 = 'Promise2: Converted to Promise';
const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
reject("Promise3: Rejected after 1sec!");
// Or throw new Error("Promise3: Rejected after 1sec!")
}, 1000);
});
Promise.all([p1, p2, p3])
.then((result) => {
console.log("result all ->", result);
})
.catch((error) => {
console.log("Error all ->", error);
});
// Output
'Error all ->' 'Promise3: Rejected after 1sec!'
There are 3 major functionalities required as part of Promise.all
Promise.all([]) instanceof Promise // true
Step 1 - Define a new Promise instance that customAll polyfill will going to return when resolve or reject invokes.
Step 2 - Define variables to capture 2 important thing, first the result array to capture the results of input promises when they fulfilled and another one is the completed counter to know when all the promises got successfully fulfilled.
Step 3 - Check for the empty iterator case and return the empty array asynchronously.
Step 4 - In this step, Loop over the promises array(iterable) and resolved each one of the promise.
Step 4.1 - If the promise got fulfilled then add the promise response to the result array (which will be returned in case all the promises got fulfilled) and increment the completed counter.
Step 4.2 - This step works like a breakpoint to resolve the new promise created at Step 2 with the result of all the promises captured part of result array , when all the promises got successfully resolved means completed counter equals to the length of the promise array.
Step 4.3 - In case if any of the input promise got rejected then the new promise got rejected with error message which was created at step 2. An error message return by the customAll
// Promise.all Polyfill
Promise.customAll = function (promisesItr) {
// Step 1: 👇 all() return a Single Promise
return new Promise((resolve, reject) => {
// Step 2: 👇
// "result" to capture promise response.
// "completed" counter to count how many promises are completed.
const result = [];
let completed = 0;
// Step 3: 👇 return empty [] if input iterable is empty.
if (promisesItr.length === 0) {
resolve(result);
}
// Step 4: 👇 Execute each promise of promisesItr
for (let i = 0; i < promisesItr.length; i++) {
Promise.resolve(promisesItr[i])
.then((response) => {
// Step 4.1: 👇 If promise fulfilled then store its response in result and increment the completed counter.
result[i] = response;
completed++;
// Step 4.2: 👇 Check if all the promises got fulfilled,
// In this case, resolve and return the result array
if (completed === promisesItr.length) {
resolve(result);
}
})
.catch((error) => {
// Step 4.3: 👇 If any promie fails, reject with error
reject(error);
});
}
});
};
Test case 1: All the promises got fulfilled
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Promise 1 Resolved after 1sec")
}, 1000);
});
const p2 = "Promise 2 Resolved !!"
const p3 = Promise.resolve("Promise3 resolved !!");
const p4 = "Promise4 resolved !!";
Promise.customAll([p1, p2, p3, p4])
.then((result) => {
console.log("Result customAll -> ", result);
})
.catch((error) => {
console.log("Error customAll ->", error);
});
/*
Output:
Result customAll -> ["Promise 1 Resolved after 1sec", "Promise 2 resolved", "Promise3 resolved !!", "Promise4 resolved !!"]
*/
Test case 2: One of the promise got rejected
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Promise 1 Resolved after 1sec")
}, 1000);
})
const p2 = Promise.reject("Promise2: Rejected Error !!");
// Or
// const p2 = new Promise((resolve, reject) => {
// setTimeout(() => {
// reject("Promise2: Rejected Error !!");
// }, 2000);
// })
const p3 = Promise.resolve("Promise3 resolved !!");
const p4 = "Promise4 resolved !!";
Promise.customAll([p1, p2, p3, p4])
.then((result) => {
console.log("Result customAll -> ", result);
})
.catch((error) => {
console.log("Error customAll ->", error);
});
/*
Output:
Result customAll -> Promise2: Rejected Error !!
*/
Promise.all is a very frequently used promise static method to call the promises asynchronously, especially when calling multiple REST APIs in any application. Understanding Promise.all polyfill in-depth will make you understand the overall working on Promise.all and what all different outputs can be produced by Promise.all in case of different scenarios.
Hope this implementation of Promise.all will help in your day to day development work, also this will definitely help you in your next javascript interview since its a very frequently asked javascript interview questions as well. Happy Coding :)
1️⃣ Promise Polyfill in JavaScript - Step by Step Explanation
2️⃣ Promise.allSettled in JavaScript explained
3️⃣ Promise.race polyfill in JavaScript explained
4️⃣ Promise.any polyfill in JavaScript explained
5️⃣ Notes to Master Promise Methods in JavaScript: all(), allSettled(), race() and any()
Anuj Sharma
A seasoned Sr. Engineering Manager at GoDaddy (Ex-Dell) with over 12+ years of experience in the frontend technologies. A frontend tech enthusiast passionate building SaaS application to solve problem. Know more about me 🚀
Be the first to share your thoughts!
No comments yet.
Start the conversation!
Build Your Portfolio
Help the Community
Strengthen Your Skills
Share your knowledge by writing a blog or quick notes. Your contribution can help thousands of frontend developers ace their interviews and grow their careers! 🚀
Anuj Sharma
Last Updated Nov 10, 2025
Find the top React Performance Optimization Techniques specific to React applications that help to make your react app faster and more responsive for the users along with some bonus techniques.
Anuj Sharma
Last Updated Nov 24, 2025
Understand step by step how to flatten nested array in javascript using recursion, also explore the flatten of complex array of object.
Alok Kumar Giri
Last Updated Jun 2, 2025
Code snippet examples which will help to grasp the concept of Hoisting in JavaScript, with solutions to understand how it works behind the scene.
Anuj Sharma
Last Updated Oct 2, 2025
Explore Polyfill for map, filter and reduce array methods in JavaScript. A detailed explanation of Map, filter and reduce polyfills in JS helps you to know the internal working of these array methods.
Anuj Sharma
Last Updated Nov 23, 2025
Find the step-by-step explanation of the useFetch custom hook in React that helps in fetching the data from an API and handling loading, error states.
Anuj Sharma
Last Updated Nov 23, 2025
Implement useThrottle Custom Hook In React (Interview) to limit the number of APi calls to improve the performance of application.
Subscribe to FrontendGeek Hub for frontend interview preparation, interview experiences, curated resources and roadmaps.
© 2025 FrontendGeek. All rights reserved