Mastering JavaScript Promises: From Basics to Advanced Techniques

Table of contents
- Types of Promises in JavaScript
- 1️⃣ Basic Promise Object
- 2️⃣ Promise with .then() and .catch()
- 3️⃣ Async/Await (Recommended for Readability)
- 4️⃣ Promise.all() (Multiple Promises in Parallel)
- 5️⃣ Promise.race() (First Promise to Resolve)
- 6️⃣ Promise.any() (First Resolved Promise, Ignores Rejections)
- 7️⃣ Promise.allSettled() (Waits for All, Doesn't Fail on Errors)
- Which One to Use?

Types of Promises in JavaScript
Promises in JavaScript can be used in multiple ways. Here’s a breakdown of the different types and ways to handle them:
1️⃣ Basic Promise Object
A Promise is an object that represents an asynchronous operation. It has three states: Pending, Resolved (Fulfilled), and Rejected.
Example:
javascriptCopyEditconst myPromise = new Promise((resolve, reject) => {
let success = true;
setTimeout(() => {
if (success) {
resolve("Promise Resolved ✅");
} else {
reject("Promise Rejected ❌");
}
}, 2000);
});
2️⃣ Promise with .then()
and .catch()
This is the traditional way to handle Promises using .then()
for success and .catch()
for errors.
Example:
javascriptCopyEditmyPromise
.then(result => console.log(result)) // Handles success
.catch(error => console.log(error)) // Handles error
.finally(() => console.log("Promise Completed 🚀")); // Always runs
✅ Pros:
✔ Simple to use
✔ Handles errors with .catch()
❌ Cons:
- If too many
.then()
calls are nested, it can become unreadable.
3️⃣ Async/Await (Recommended for Readability)
Instead of .then()
, async/await
allows you to write asynchronous code that looks synchronous.
Example:
javascriptCopyEditasync function fetchData() {
try {
let response = await fetch("https://jsonplaceholder.typicode.com/todos/1");
let data = await response.json();
console.log("Data received:", data);
} catch (error) {
console.error("Error fetching data:", error);
}
}
fetchData();
✅ Pros:
✔ Cleaner syntax, avoids callback hell
✔ Easier debugging
❌ Cons:
- Must be used inside an
async
function
4️⃣ Promise.all() (Multiple Promises in Parallel)
Used when multiple promises need to be executed at the same time, and we want to wait for all of them to resolve.
Example:
javascriptCopyEditconst p1 = new Promise(resolve => setTimeout(() => resolve("P1 Done"), 2000));
const p2 = new Promise(resolve => setTimeout(() => resolve("P2 Done"), 3000));
const p3 = new Promise(resolve => setTimeout(() => resolve("P3 Done"), 1000));
Promise.all([p1, p2, p3])
.then(results => console.log(results)) // ["P1 Done", "P2 Done", "P3 Done"]
.catch(error => console.log(error));
✅ Pros:
✔ Runs all promises in parallel (faster execution)
✔ Resolves when all are done
❌ Cons:
- If one promise fails, everything fails
5️⃣ Promise.race() (First Promise to Resolve)
Returns the result of the first promise that resolves or rejects.
Example:
javascriptCopyEditPromise.race([p1, p2, p3])
.then(result => console.log("First Done:", result)) // Whichever is fastest
.catch(error => console.log(error));
✅ Pros:
✔ Useful for timeouts (fastest response wins)
❌ Cons:
- Ignores other promises once one is resolved/rejected
6️⃣ Promise.any() (First Resolved Promise, Ignores Rejections)
Returns the first successfully resolved promise and ignores rejected ones.
Example:
javascriptCopyEditconst failPromise = new Promise((_, reject) => setTimeout(() => reject("Failed"), 500));
const fastSuccess = new Promise(resolve => setTimeout(() => resolve("Success!"), 200));
Promise.any([failPromise, fastSuccess])
.then(result => console.log(result)) // "Success!"
.catch(error => console.log("All promises failed:", error));
✅ Pros:
✔ If one promise fails, it still waits for a successful one
❌ Cons:
- If all fail, it throws
AggregateError
7️⃣ Promise.allSettled() (Waits for All, Doesn't Fail on Errors)
Returns an array with results of all promises (resolved or rejected).
Example:
javascriptCopyEditPromise.allSettled([p1, failPromise, p2])
.then(results => console.log(results));
✅ Pros:
✔ Unlike Promise.all()
, it doesn't fail if one promise rejects
❌ Cons:
- Slightly slower than
Promise.all()
Which One to Use?
Type | When to Use |
.then().catch() | Simple async operations |
async/await | Readable and modern approach |
Promise.all() | When all promises must complete |
Promise.race() | When you need the fastest response |
Promise.any() | When you need at least one successful promise |
Promise.allSettled() | When you need results of all, even failures |
Subscribe to my newsletter
Read articles from Harsh Goswami directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Harsh Goswami
Harsh Goswami
Harsh | Frontend Developer 👨💻 I’m a passionate frontend developer with 2 years of experience at Softcolon Pvt Ltd. I specialize in creating responsive, user-centric web applications using modern frameworks like React.js, Next.js, and Remix. Currently, I’m focused on enhancing my skills in web development and exploring new technologies. When I'm not coding, you’ll find me collaborating with developers worldwide, participating in hackathons, or working on my portfolio website. I’m also considering starting a blog to share insights and connect with the frontend community. Let’s build amazing things together!