Problem Statement
Explain Promises in JavaScript. How do they work and why are they better than callbacks?
Explanation
A Promise is an object representing the eventual completion or failure of an asynchronous operation.
Promises have three states:
Pending is the initial state. The operation has not completed yet.
Fulfilled means the operation completed successfully. The promise has a value.
Rejected means the operation failed. The promise has a reason for failure.
How Promises work:
You create a Promise with the new Promise constructor. Pass a function that receives resolve and reject callbacks. Call resolve with the result when operation succeeds. Call reject with the error when operation fails. Use .then to handle success and .catch to handle errors.
Why Promises are better than callbacks:
Cleaner syntax without deep nesting.
Can chain multiple operations easily. Better error handling with catch.
Can use Promise all for parallel operations.
Returns a value that can be passed around. Avoid callback hell.
Promise methods:
Then for handling success. Catch for handling errors. Finally for cleanup code. Promise all for waiting on multiple promises. Promise race for first completed promise. Promise allSettled for all results regardless of success or failure.
Promises are fundamental to modern JavaScript and understanding them is essential for working with async code.
Code Solution
SolutionRead Only
// Creating a Promise
const myPromise = new Promise((resolve, reject) => {
// Asynchronous operation
setTimeout(() => {
const success = true;
if (success) {
resolve('Success!'); // Fulfilled
} else {
reject('Failed!'); // Rejected
}
}, 1000);
});
// Using the Promise
myPromise
.then(result => {
console.log(result); // 'Success!'
})
.catch(error => {
console.log(error);
})
.finally(() => {
console.log('Cleanup');
});
// Chaining Promises
fetchUser()
.then(user => {
console.log('Got user:', user);
return fetchPosts(user.id);
})
.then(posts => {
console.log('Got posts:', posts);
return fetchComments(posts[0].id);
})
.then(comments => {
console.log('Got comments:', comments);
})
.catch(error => {
console.log('Error in chain:', error);
});
// Promise.all() - parallel operations
Promise.all([
fetch('/api/users'),
fetch('/api/posts'),
fetch('/api/comments')
])
.then(([users, posts, comments]) => {
console.log('All data loaded');
})
.catch(error => {
console.log('One failed:', error);
});
// Converting callback to Promise
function readFilePromise(filename) {
return new Promise((resolve, reject) => {
fs.readFile(filename, 'utf8', (error, data) => {
if (error) {
reject(error);
} else {
resolve(data);
}
});
});
}
// Callback hell vs Promises
// Callback hell:
getData(function(a) {
getMoreData(a, function(b) {
getEvenMoreData(b, function(c) {
console.log(c);
});
});
});
// With Promises:
getData()
.then(a => getMoreData(a))
.then(b => getEvenMoreData(b))
.then(c => console.log(c));