I’ve been using promises for a while, but I’m just now really understanding how they work.
What I Thought I Knew
I thought promises were just:
fetch(url)
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));
That’s the basics, but there’s more.
Promise States
A promise can be in three states:
- Pending: Not finished yet
- Fulfilled: Completed successfully
- Rejected: Failed with an error
Once a promise is fulfilled or rejected, it can’t change.
Creating Promises
I’m learning to create my own promises:
function delay(ms) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(`Waited ${ms}ms`);
}, ms);
});
}
delay(1000).then(message => console.log(message));
Promise Chaining
Chaining is powerful when you understand it:
fetch('/api/user')
.then(response => {
if (!response.ok) throw new Error('Failed');
return response.json();
})
.then(user => {
console.log(user);
return fetch(`/api/posts?userId=${user.id}`);
})
.then(response => response.json())
.then(posts => console.log(posts))
.catch(error => console.error(error));
Each .then() returns a new promise.
Error Handling
I’m learning proper error handling:
promise
.then(result => {
// Handle success
})
.catch(error => {
// Handle any error in the chain
})
.finally(() => {
// Always runs, success or failure
});
Promise Methods
Promise.all(): Wait for all promises:
const [users, posts, comments] = await Promise.all([
fetchUsers(),
fetchPosts(),
fetchComments()
]);
Promise.race(): First one to finish wins:
const result = await Promise.race([
fetchFromAPI1(),
fetchFromAPI2()
]);
Promise.allSettled(): Wait for all, even if some fail:
const results = await Promise.allSettled([
promise1,
promise2,
promise3
]);
Common Mistakes
Forgetting to return: Breaking the chain:
// Bad
promise.then(result => {
doSomething(result); // Not returning!
}).then(result => {
// result is undefined
});
// Good
promise.then(result => {
return doSomething(result);
}).then(result => {
// result has the value
});
Not catching errors: Unhandled promise rejections.
Nesting promises: Creating callback hell with promises.
What’s Clicking
Promises are about managing asynchronous operations in a clean way. They’re not magic they’re just objects that represent future values.
Understanding promises deeply is making async/await make more sense too, since async/await is built on promises.