JavaScript Promises
Handle asynchronous operations elegantly
🤝 What are Promises?
A Promise is an object representing the eventual completion or failure of an asynchronous operation. It's a cleaner alternative to callbacks.
// Creating a simple promise
const myPromise = new Promise((resolve, reject) => {
const success = true;
if (success) {
resolve('Operation successful!');
} else {
reject('Operation failed!');
}
});
myPromise.then(result => console.log(result));
Output:
Operation successful!
Promise States
Pending
Initial state, not fulfilled or rejected
const promise = new Promise(() => {
// Still running...
});
Fulfilled
Operation completed successfully
resolve('Success!');
Rejected
Operation failed
reject('Error occurred!');
Settled
Either fulfilled or rejected
// Promise is settled
// (no longer pending)
🔹 Creating Promises
Here's how to create and use promises:
// Creating a promise that resolves after 2 seconds
function delay(ms) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(`Waited for ${ms} milliseconds`);
}, ms);
});
}
// Using the promise
delay(2000).then(message => {
console.log(message);
});
// Promise that might fail
function randomSuccess() {
return new Promise((resolve, reject) => {
const random = Math.random();
if (random > 0.5) {
resolve('Success! Random number: ' + random);
} else {
reject('Failed! Random number: ' + random);
}
});
}
Output:
(After 2 seconds...)
Waited for 2000 milliseconds
🔹 Promise Methods
Promises have several useful methods:
const promise = new Promise((resolve, reject) => {
const success = Math.random() > 0.5;
setTimeout(() => {
if (success) {
resolve('Data loaded successfully');
} else {
reject(new Error('Failed to load data'));
}
}, 1000);
});
// .then() - handles success
promise.then(data => {
console.log('Success:', data);
});
// .catch() - handles errors
promise.catch(error => {
console.log('Error:', error.message);
});
// .finally() - runs regardless of outcome
promise.finally(() => {
console.log('Promise completed');
});
// Chaining all together
promise
.then(data => console.log('Success:', data))
.catch(error => console.log('Error:', error.message))
.finally(() => console.log('Cleanup completed'));
Output (if successful):
Success: Data loaded successfully
Promise completed
Cleanup completed
🔹 Promise Chaining
Chain multiple promises together:
// Simulating API calls
function fetchUser(id) {
return new Promise(resolve => {
setTimeout(() => {
resolve({ id: id, name: 'John Doe' });
}, 1000);
});
}
function fetchUserPosts(userId) {
return new Promise(resolve => {
setTimeout(() => {
resolve(['Post 1', 'Post 2', 'Post 3']);
}, 1000);
});
}
function fetchPostComments(post) {
return new Promise(resolve => {
setTimeout(() => {
resolve([`Comment on ${post}`, `Reply to ${post}`]);
}, 1000);
});
}
// Chaining promises
fetchUser(123)
.then(user => {
console.log('User:', user.name);
return fetchUserPosts(user.id);
})
.then(posts => {
console.log('Posts:', posts);
return fetchPostComments(posts[0]);
})
.then(comments => {
console.log('Comments:', comments);
})
.catch(error => {
console.log('Error in chain:', error);
});
Output:
(After 1 second...) User: John Doe
(After 2 seconds...) Posts: ["Post 1", "Post 2", "Post 3"]
(After 3 seconds...) Comments: ["Comment on Post 1", "Reply to Post 1"]
🔹 Promise.all() and Promise.race()
Handle multiple promises at once:
// Multiple promises
const promise1 = Promise.resolve('First');
const promise2 = Promise.resolve('Second');
const promise3 = Promise.resolve('Third');
// Promise.all() - waits for all to complete
Promise.all([promise1, promise2, promise3])
.then(results => {
console.log('All results:', results);
});
// Promise.race() - returns first completed
Promise.race([
new Promise(resolve => setTimeout(() => resolve('Fast'), 1000)),
new Promise(resolve => setTimeout(() => resolve('Slow'), 3000))
])
.then(result => {
console.log('First result:', result);
});
// Real example: Loading multiple resources
const loadUser = fetch('/api/user');
const loadPosts = fetch('/api/posts');
const loadComments = fetch('/api/comments');
Promise.all([loadUser, loadPosts, loadComments])
.then(responses => {
console.log('All data loaded');
// Process all responses
})
.catch(error => {
console.log('One or more requests failed:', error);
});
Output:
All results: ["First", "Second", "Third"]
(After 1 second...) First result: Fast