Promise.then() / catch() / finally()
Handles resolved/rejected promises and runs cleanup with finally().
promise.then(onFulfilled).catch(onRejected).finally(onFinally)This static page keeps the syntax and examples indexed for search, while the coding app handles interactive exploration and saved references.
What it does
Overview
Handles resolved/rejected promises and runs cleanup with finally().
Syntax: promise.then(callbackFn).catch(callbackFn).finally(callbackFn). Promise.prototype.then(), catch(), and finally() are the fundamental methods for managing asynchronous control flow in JavaScript. then() appends fulfillment and rejection handlers, returning a new promise that resolves to the return value of the executed callback. This enables promise chaining. These methods operate via the microtask queue; when a promise settles, its callbacks are prioritized over macrotasks like setTimeout, ensuring they execute before the browser yields to the event loop. catch() is a shorthand for then(null, onRejected), specifically catching upstream rejections. finally() executes a callback regardless of settlement state, which is vital for cleanup operations. An important edge case: finally() does not receive the resolution value and typically passes the previous promise state through to the next link in the chain, unless the finally callback itself throws an error or returns a rejected promise. IE is not supported natively.
Quick reference
Syntax
promise.then(onFulfilled).catch(onRejected).finally(onFinally)
Inputs
Parameters
See it in practice
Examples
Chaining and Value Transformation
Promise.resolve(10)
.then(function(val) {
return val * 5;
})
.then(function(val) {
console.log('Transformed value:', val);
});Transformed value: 50
Each call to then() returns a new promise. Returning a value from the callbackFn allows the subsequent then() to receive that value.
Error Recovery with Catch
Promise.reject('Network Failure')
.catch(function(err) {
console.log('Error logged:', err);
return 'Default Data';
})
.then(function(data) {
console.log('App state:', data);
});Error logged: Network Failure App state: Default Data
The catch() method handles the rejection. By returning a string, it fulfills the promise chain, allowing subsequent then() blocks to execute successfully.
Cleanup with Finally
var isBusy = true;
Promise.resolve('Operation Successful')
.then(function(msg) {
console.log(msg);
})
.catch(function(err) {
console.error(err);
})
.finally(function() {
isBusy = false;
console.log('Status updated, isBusy:', isBusy);
});Operation Successful Status updated, isBusy: false
The finally() callback runs regardless of whether the promise was fulfilled or rejected, making it the standard location for teardown logic like stopping loading spinners.
Debug faster
Common Errors
LogicError
Cause: Forgetting to return a value or a new promise within a then() block, which causes the next link in the chain to be resolved with undefined.
Fix: Always return the result of the asynchronous operation or the desired value to pass it down the chain.
promise.then(function(res) { fetchOther(res); }).then(function(final) { /* final is undefined */ });ReferenceError
Cause: Nesting promises (the 'Promise Pyramid') instead of returning them to flatten the chain, which complicates error handling and readability.
Fix: Return the inner promise from the callbackFn so it can be handled by a top-level then() or catch().
doA().then(function(a) { doB(a).then(function(b) { console.log(b); }); });Runtime support
Compatibility
Source: MDN Web Docs
Common questions
Frequently Asked Questions
Handles resolved/rejected promises and runs cleanup with finally().
onFulfilled: Runs when the promise resolves. onRejected: Runs when the promise rejects. onFinally: Runs after settle (resolve or reject).
LogicError: Always return the result of the asynchronous operation or the desired value to pass it down the chain. ReferenceError: Return the inner promise from the callbackFn so it can be handled by a top-level then() or catch().