In JavaScript, executing multiple promises sequentially refers to running asynchronous tasks in a specific order, ensuring each task is completed before the next begins. This is essential when tasks depend on the results of previous ones, ensuring correct flow and preventing unexpected behavior.
Following are certain approaches through which we could easily sequentially execute multiple promises:
Approach 1: Using Promise.then() Chaining
One of the simplest ways to execute promises sequentially is by chaining .then() calls.
const promise1 = new Promise((resolve) =>
setTimeout(() => resolve("Promise 1 resolved"), 1000)
);
const promise2 = new Promise((resolve) =>
setTimeout(() => resolve("Promise 2 resolved"), 500)
);
function executeSequentially() {
promise1
.then((result1) => {
console.log(result1);
return promise2;
})
.then((result2) => {
console.log(result2);
});
}
executeSequentially();
Output

In this example
- promise1 resolves after 1 second with the message "Promise 1 resolved".
- promise2 resolves after 0.5 seconds with the message "Promise 2 resolved".
- This function chains the promises so that promise2 waits for promise1 to resolve first.
- The first .then() handles the resolution of promise1, logs the result, and returns promise2 to ensure it runs after promise1.
- The second .then() handles the resolution of promise2 and logs its result.
- Even though promise2 resolves faster, it only starts after promise1 resolves because promise2 is returned in the first .then().
- This ensures that promise2 waits for promise1 to finish first, achieving sequential execution.
Approach 2: Using async/await
The async/await syntax allows us to write asynchronous code in a synchronous manner. This makes it easier to handle promises and ensures they are executed sequentially.
const fetch1 = () =>
new Promise((resolve) =>
setTimeout(() => resolve("Data from promise 1"), 1000)
);
const fetch2 = () =>
new Promise((resolve) =>
setTimeout(() => resolve("Data from promise 2"), 2000)
);
const fetch3 = () =>
new Promise((resolve) =>
setTimeout(() => resolve("Data from promise 3"), 3000)
);
const executeSequence = async () => {
const res1 = await fetch1();
console.log(res1);
const res2 = await fetch2();
console.log(res2);
const res3 = await fetch3();
console.log(res3);
};
executeSequence();
Output

In this example
- fetch1, fetch2, and fetch3 are three promises that resolve after 1, 2, and 3 seconds, respectively.
- executeSequence is an async function that uses await to wait for each promise to resolve before moving to the next.
- The function waits for fetch1 to resolve, then logs its result.
- After fetch1 finishes, the function waits for fetch2 to resolve and logs its result.
- Once fetch2 resolves, the function waits for fetch3 to finish and logs its result, ensuring sequential execution.
Why Execute Promises Sequentially?
Executing promises sequentially can be important when:
- The result of one promise is needed by the next one.
- The operations must happen in a specific order, such as fetching data in stages or when performing a series of tasks like file handling or database transactions.
async/await vs .then()
Feature | async/await | .then() |
|---|---|---|
Syntax | Cleaner and more readable | Can get complex with multiple chained promises |
Error Handling | Use try/catch for better readability | Uses .catch() for error handling |
Usage | Preferred for newer code bases and readability | Common in older codebases or complex chains |