How Do I Use JavaScript Promise Methods?
JavaScript Promises come with methods for handling the settled response of asynchronous operations, such as .then(), .catch(), and .finally(). As mentioned in our explanation of asynchronous methods, Javascript Promises represent the eventually completion of a task. Once settled, a Promise is either resolved or rejected. Promise methods allow us to act after completion, and each of them returns another Promise.
The then() method
If a settled Promise is resolved, we can trigger code to run using the .then() method. Since this method returns another Promise, it’s possible to chain another .then() method. Thus, multiple actions can be triggered in series.
function waitSomeSeconds(sec) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(`Promise resolved after ${sec} seconds.`);
}, sec * 1000);
});
}
console.log("Before waiting.");
waitSomeSeconds(3)
.then(result => {
console.log(result);
return waitSomeSeconds(3)
})
.then(result => {
console.log(result);
});
console.log("Did not wait.");
Returns immediately:
Before waiting.
Did not wait.
After 3 seconds:
Promise resolved after 3 seconds.
After 6 seconds:
Promise resolved after 3 seconds.
Nesting the then() method behaves the same way. It's more difficult to read but in certain use cases may be handy:
console.log("Before waiting.");
waitSomeSeconds(3)
.then(result => {
console.log(result);
return waitSomeSeconds(3)
.then(result => {
console.log(result);
});
});
console.log("Did not wait.");
The catch() method
The .catch() method allows us run any code we wish after a Promise has been rejected. We could throw an error or call console.error(), passing it the reason for rejection. Alternately, we might call another asynchronous operation and handle its response with another set of then() and catch() methods.
function waitWithError(sec) {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject(`Promise rejected after ${sec} seconds.`);
}, sec * 1000);
});
}
console.log("Before waiting.")
waitWithError(3)
.then(result => {
console.log(result);
})
.catch(err => {
console.error(err);
});
console.log("Did not wait.");
Returns immediately:
Before waiting.
Did not wait.
After 3 seconds:
Promise rejected after 3 seconds.
A single catch() method after a series of chained then() methods will catch all errors. To handle each error separately, we need a way differentiate between them. Alternately, we can catch early rejections using the second argument of then(). This works because .catch() is simply short for .then(undefined, onRejected):
function waitWithError(sec) {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject(`Promise rejected after ${sec} seconds.`);
}, sec * 1000);
});
}
console.log("Before waiting.")
waitWithError(3)
.then(result => {
console.log(result);
}, err => {
console.error(`First ${err}`)
})
.then(result => {
return waitWithError(4)
})
.catch(err => {
console.error(`Second ${err}`)
});
console.log("Did not wait.");
Returns immediately:
Before waiting.
Did not wait.
After 3 seconds:
First Promise rejected after 3 seconds.
After 7 seconds:
Second Promise rejected after 4 seconds.
By catching the error with the first function, we allow the second function to be called. To avoid calling the second function, throw an error when the first error is caught.
The finally() method
Code in a finally() method will run after a Promise settles whether it resolves or rejects. It’s a great way to run code that requires waiting for the Promise to settle but doesn’t care which way it went. Instead of writing the same code in both .then() and .catch(), you can put it here.
function waitSomeTime(sec) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (Math.random() > .5) {
resolve(`Promise resolved after ${sec} seconds.`);
} else {
reject(`Promise rejected after ${sec} seconds.`);
}
}, sec * 1000);
});
}
console.log("Before waiting.")
waitSomeTime(3)
.then(result => {
console.log(result);
})
.catch(err => {
console.error(err);
})
.finally(result => {
console.log("Processing complete.")
});
console.log("Did not wait.");
Returns immediately:
Before waiting.
Did not wait.
After 3 seconds (one or the other):
Promise resolved after 3 seconds.
Promise rejected after 3 seconds.
Finishing immediately with:
Processing complete.
Related posts:
Helpful references:
Have feedback on this topic?