The Most Important Thing You Don't Know About Promises

Full Stack Developer | Freelancer | JavaScript | React | Nodejs.
Loves sharing knowledge through technical articles.
Dev.to: https://dev.to/myogeshchavan97
https://linktr.ee/myogeshchavan97
Search for a command to run...

Full Stack Developer | Freelancer | JavaScript | React | Nodejs.
Loves sharing knowledge through technical articles.
Dev.to: https://dev.to/myogeshchavan97
https://linktr.ee/myogeshchavan97
Great article. I have stuck in this problem before. I wonder if there's a way to solve this by using async-await instead of promises.
Himanshu Kumar If you're using async/await, you don't need to worry about this problem because when using await keyword, the next line will not be executed until the promise we're awaiting for gets resolved/rejected.
Yogesh Chavan That makes sense. Thanks for clarifying.
Awesome content. Thanks Yogesh! I was wondering as for API call we mostly use axios which also returns a Promise by default, we will not have to explicitly return a promise from inside a then block. Obviously for other use cases where things don't return promise we have to do the one you did. Please correct me if I am wrong.
Thanks SOIF RIWAJ.
Yes, for axios we don't need to deal with this issue most of the time. But If you're doing some asynchronous operation in the .then handler then you need to be aware of this issue.
Wow-some article as usual Yogesh Chavan, this is a refreshment for me 🤗, thanks a lot for sharing 😊
In this tutorial, you will build a Task Management App using Next.js 16 and Prisma 7 from scratch. By creating this app, you will learn: How to set up Prisma 7 with the new Rust-free architecture How to configure a database with Prisma's driver ada...

If you're a React/Next.js developer who diligently updated your packages last week after the critical React2Shell vulnerability (CVE-2025-55182), I have some frustrating news: you need to update again. Security researchers, while probing the patches ...

Is your React app dragging its feet, but you can’t pinpoint the cause? You might think you’re following the best practices, but some common development patterns are actually degrading your app’s performance behind the scenes. In this article, we’ll u...

How to Use Separate SSH Keys for Company and Personal GitHub Accounts Managing multiple GitHub accounts is a common challenge for developers who juggle both personal and professional projects. It becomes even more complex when you want to use differe...

Have you ever built a React app only to realize that users from different countries can't use it effectively because it only supports English? In this tutorial, you'll learn how to build truly global React application using internationalization (i18n...

Take a look at the below code:
const promise = new Promise((resolve, reject) => {
resolve();
});
promise
.then(() => {
console.log('first');
})
.then(() => {
console.log('second');
})
.then(() => {
console.log('third');
})
.catch((error) => {
console.log('error', error);
});
If you execute the above code, you'll see the following output:

As you know each .then handler will be executed one after the another and the value returned from the previous .then handler is passed to the next .then handler so we get the output of the above code as:
first
second
third
which is as expected.
But now, take a look at the below code:
const promise = new Promise((resolve, reject) => {
resolve();
});
promise
.then(() => {
console.log('first');
})
.then(() => {
setTimeout(() => {
console.log('second');
}, 2000);
})
.then(() => {
setTimeout(() => {
console.log('third');
}, 1000);
});
If you execute the above code you will see the following output:

We're getting the output as:
first
third
second
In the above code, the second .then handler has a setTimeout function call with 2000 milliseconds(2 seconds) as the timeout so it will not be executed immediately, but the third .then will be executed before the second .then handler as it has a 1000 millisecond(1 second) timeout.
Therefore, we're seeing first printed immediately and after 1 second, third will be printed and after 2 seconds second will be printed.
So If any .then handler is making an API call or doing some long-running operation then the next .then handler function might be executed immediately even If the long-running operation in the previous .then handler is not completed yet.
When you attach multiple
.thenhandlers, it’s not guaranteed that the next.thenhandler will be called only after the previous.thenhandler finishes if there is additional asynchronous code inside the handler.
There is a way to fix this default behavior.
We can return a new promise from the second .then handler and only call resolve or reject once we are done with our API call or any other long-running operation.
This will guarantee that the next .then will always be executed after the previous one has finished.
This is because when we call a promise, the Promise will wait until we explicitly call resolve or reject inside the promise.
The following is the code that will maintain the order sequence:
const promise = new Promise((resolve, reject) => {
resolve();
});
promise
.then(() => {
console.log('first');
})
.then(() => {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('second');
resolve();
}, 2000);
});
})
.then(() => {
setTimeout(() => {
console.log('third');
}, 1000);
});
As you can see, we're returning a promise from the second .then handler so the next .then handler will be executed only if the second .then handler resolves.
If you execute the above code you will see the following output:

As you can see now, each .then handle is executed only after the previous one is finished executed.
That's it about this article.
Check out my recently published Mastering Redux course.
In this course, you will learn:
and then finally we'll build a complete food ordering app from scratch with stripe integration for accepting payments and deploy it to the production.
Want to stay up to date with regular content regarding JavaScript, React, Node.js? Follow me on LinkedIn.