Skip to content

Promises

Promises represent the eventual completion (or failure) of an asynchronous operation. Introduced in ES6 (2015), they provide a cleaner alternative to callback-based asynchronous code.

Callbacks led to “callback hell” with nested functions:

// Callback hell
getData(function(a) {
getMoreData(a, function(b) {
getEvenMoreData(b, function(c) {
console.log("Final result:", c);
}, function(err) {
console.error(err);
});
}, function(err) {
console.error(err);
});
}, function(err) {
console.error(err);
});

Promises enable chaining and cleaner error handling:

// Promise chaining
getData()
.then(a => getMoreData(a))
.then(b => getEvenMoreData(b))
.then(c => console.log("Final result:", c))
.catch(err => console.error(err));
// Creating a Promise
const fetchUser = (id) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (id > 0) {
resolve({ id, name: "Alice" });
} else {
reject(new Error("Invalid ID"));
}
}, 1000);
});
};
// Using the Promise
fetchUser(1)
.then(user => console.log(user))
.catch(err => console.error(err));
// Promise.all - run multiple promises in parallel
const promises = [
fetch("/api/users"),
fetch("/api/posts"),
fetch("/api/comments")
];
Promise.all(promises)
.then(results => console.log("All done:", results))
.catch(err => console.error("One failed:", err));
// Promise.race - use first to complete
Promise.race(promises)
.then(result => console.log("First done:", result));
  • Readable: Flat chain instead of nested callbacks
  • Error handling: Single .catch() handles all errors in chain
  • Composable: Easy to combine multiple async operations
  • State: Promises have three states (pending, fulfilled, rejected)
  • Guaranteed: .then() always called asynchronously
  • A promise can only be resolved or rejected once
  • .then() returns a new promise, enabling chaining
  • Errors in .then() are caught by subsequent .catch()
  • Unhandled promise rejections can crash Node.js apps
  • Promise.all() fails if any promise rejects
  • Use Promise.allSettled() if you want all results regardless of failures
// Promise.allSettled - get all results (ES2020)
Promise.allSettled([
Promise.resolve(1),
Promise.reject("error"),
Promise.resolve(3)
]).then(results => {
console.log(results);
// [
// { status: 'fulfilled', value: 1 },
// { status: 'rejected', reason: 'error' },
// { status: 'fulfilled', value: 3 }
// ]
});
  1. Create a promise that resolves with “Success” after 2 seconds.

    Answer
    const promise = new Promise((resolve) => {
    setTimeout(() => resolve("Success"), 2000);
    });
  2. What’s the difference between Promise.all() and Promise.race()?

    Answer `Promise.all()` waits for all promises to resolve (or one to reject). `Promise.race()` resolves/rejects as soon as the first promise settles.
  3. How do you convert a callback-based function to use Promises?

    Answer
    function callbackFn(arg, callback) { /* ... */ }
    function promiseFn(arg) {
    return new Promise((resolve, reject) => {
    callbackFn(arg, (err, result) => {
    if (err) reject(err);
    else resolve(result);
    });
    });
    }