JavaScript Promise.then() method is a way to schedule callback functions for the eventual completion of a promise which is either fulfillment or rejection. It takes up to two arguments: callback functions for the success and failure cases of the Promise.
The Promise.then() registers two callbacks that will be called when the Promise’s asynchronous operation finishes successfully (onFullfilled) or an error occurs (onRejected).
Syntax
p.then(onFulfilled[, onRejected]);
p.then(value => {
// fulfillment
}, reason => {
// rejection
});
Parameters
The then() function takes two callback function parameters:
- onFulfilled(): JavaScript will call onFulfilled() function if the underlying async operation succeeded. It is an optional parameter. The onFulfilled() function has one argument, the fulfillment value. If it is not a function, it is internally replaced with an “Identity” function (it returns the received argument).
- onRejected(): JavaScript will call onRejected() function if the underlying async operation failed. It is an optional parameter. The onRejected() function has one argument, the rejection reason. If it is not a function, it is internally replaced with a “Thrower” function (it throws an error it received as an argument).
Return Value
The .then() function returns that Promise is fulfilled or rejected, and the corresponding handler function (onFulfilled or onRejected) will be called asynchronously (scheduled in the current thread loop).
Example 1
const promise = new Promise(function executor(resolve, reject) {
// Fulfill the promise with value '11' after 500 ms.
setTimeout(() => resolve(11), 500);
});
promise.then(value => {
console.log(value)
});
Output
11
A promise always starts in the pending state. If the Promise turns to the fulfilled state, JavaScript calls the onFulfilled() function.
If you call .then() on the already fulfilled Promise, JavaScript will immediately call onFulfilled() function.
In our case, we are faking asynchronous operations using the setTimeOut() function. After 500ms, we are resolving the Promise. So inside a then() function, you will get the resolved value.
If the Promise changes to the rejected state, or if you call then() already rejected promiseected, JavaScript calls onRejected().
Example 2
const promise = Promise.reject(new Error('Something went wrong!'));
promise.then(null, err => {
console.log(err.message);
});
Output
Something went wrong!
Both onFulfilled() and onRejected() are optional.
If onFulfilled() is null, like in the above example, JavaScript will do nothing if the Promise is fulfilled.
If you call .then() without an onRejected() function and the Promise rejects, that will lead to an unhandled rejection error message.
Promise chaining
Promise chaining is one of the key reasons why promises are so useful. The .then() function returns a promise p, and if your onFulfilled() function returns the promise q, p will adopt the state of q.
Because of promise chaining, you don’t need to catch errors in each individual then(). If you put .catch() at the end of your promise chain, any errors in the promise chain will bypass the rest of the promise chain and go straight to your .catch() error handler.
Example
Promise.resolve(1).
then(() => Promise.resolve(2)).
then(() => Promise.reject(new Error('Something went wrong'))).
then(() => console.log('Yello')).
catch(function errorHandler(err) {
console.log(err.message);
});
Output
Something went wrong
That’s it.