JavaScript Promises Explained for Beginners (Examples)
JavaScript promises explained for beginners: learn pending, fulfilled and rejected, then(), catch(), finally() and Promise.all with simple runnable examples.
JavaScript promises explained for beginners: learn pending, fulfilled and rejected, then(), catch(), finally() and Promise.all with simple runnable examples.
What is a JavaScript promise? A promise is an object that stands for a value you do not have yet, but will get later. Think of ordering food at a restaurant: you get a receipt now, and the meal arrives later. The receipt is the promise. In this beginner guide you will learn what promises are, how to use then(), catch() and finally(), and how to create your own.
You do not need any experience with promises. If you already know functions and the Fetch API, you are ready. We define every new word as we go.
Some tasks take time, like loading data from a server. JavaScript does not stop and wait. It keeps running the rest of your code. This is called asynchronous code, which just means 'not happening in order, right now'.
Before promises, people used callbacks (functions passed into other functions to run later). Many nested callbacks became hard to read. Promises give us a cleaner way to say: 'do this, and when it finishes, do that'.
| State | Meaning | Example |
|---|---|---|
| pending | The work is still running | Waiting for a server reply |
| fulfilled | The work finished successfully | Data arrived |
| rejected | The work failed | No internet connection |
A promise starts as pending. It then becomes fulfilled or rejected, and it never changes again. Once it has a result, we say it is settled.
const promise = new Promise((resolve, reject) => {
const ok = true;
if (ok) {
resolve('It worked!');
} else {
reject('Something went wrong');
}
});
console.log(promise);Line 1 creates a new promise. We give it a function with two helpers: resolve and reject. Line 2 makes a simple true/false value. If it is true, we call resolve() with a success message. Otherwise we call reject() with an error message. The last line prints the promise object.
promise
.then((message) => {
console.log('Success:', message);
})
.catch((error) => {
console.log('Error:', error);
});The then() method runs when the promise is fulfilled, and it receives the value passed to resolve(). The catch() method runs when the promise is rejected, and it receives the value passed to reject(). With ok set to true, you will see: Success: It worked!
function wait(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
wait(2000).then(() => {
console.log('Two seconds have passed');
});The wait function returns a promise. Inside, setTimeout calls resolve after the number of milliseconds you give (1000 ms is one second). We call wait(2000) and use then() to run code after two seconds. Notice that we did not need reject here because nothing can fail.
Each then() returns a new promise, so you can link steps one after another. This is called chaining.
Promise.resolve(5)
.then((n) => n * 2)
.then((n) => n + 1)
.then((n) => {
console.log(n); // 11
});Promise.resolve(5) makes a promise that is already fulfilled with 5. The first then() doubles it to 10. Whatever a then() returns is passed to the next one, so the second adds 1 to make 11. The last step prints 11.
fetch('https://jsonplaceholder.typicode.com/todos/1')
.then((response) => response.json())
.then((todo) => console.log(todo.title))
.catch((error) => console.log('Failed:', error))
.finally(() => console.log('Done'));fetch() returns a promise. The first then() turns the reply into JSON, which is also a promise. The second then() prints the title. If anything fails, catch() handles it. The finally() method runs at the end whether it worked or not, which is perfect for hiding a loading message.
const a = wait(1000).then(() => 'A');
const b = wait(2000).then(() => 'B');
Promise.all([a, b]).then((results) => {
console.log(results); // ['A', 'B']
});Promise.all takes a list of promises and waits for all of them. It gives back an array of results in the same order. Both timers run at the same time, so it takes about 2 seconds, not 3. If one promise fails, Promise.all fails too.
The async/await syntax is just a friendlier way to write promises. Under the hood it uses the same thing. Here is the delay example written both ways.
// with then()
wait(1000).then(() => console.log('Hi'));
// with async/await
async function run() {
await wait(1000);
console.log('Hi');
}
run();The await keyword pauses inside the async function until the promise settles, then gives you the value. Learning promises first makes async/await much easier to understand.
A promise is an object that represents a result that will arrive later. It can end up fulfilled with a value or rejected with an error. You use then() and catch() to react to either outcome.
A callback is a function you pass in to be run later. A promise is an object you get back that you can attach steps to. Promises are easier to chain and handle errors in, so they avoid deeply nested code.
resolve() marks the promise as successful and passes along a value. reject() marks it as failed and passes along an error. Only the first one you call has any effect.
They are the same thing underneath. Async/await reads more like normal top-to-bottom code, so many beginners prefer it. You still need to understand promises to use it well.
If a promise is rejected and nothing handles it, you get an unhandled rejection error in the console. Always add catch() or use try/catch with await so failures are handled.
Ready for the easier syntax? Continue the path with our async/await guide.
Read async/await for beginnersWant help building a web app or learning to code with guidance? Talk to the Fepiq team.
Contact FepiqOccasional, no-fluff notes on shipping modern software — startups, automation, Laravel, Shopify and more. No spam, unsubscribe anytime.
Keep reading
Learn SQL CASE WHEN step by step. This beginner guide shows how to label, group and sort data with simple examples you can copy and run today.
PostgreSQL ILIKE explained for beginners: search text without worrying about case, learn % and _ wildcards, and copy simple examples you can run today.
Let's build something
Book a free discovery call. We'll listen, ask sharp questions, and send you a proposal within 3 business days.