**Promise.finally()** is the Promise equivalent of the `finally` block in try/catch. It receives no arguments (can't distinguish resolved from rejected) and runs cleanup code like hiding loading spinners, releasing resources, or resetting state. It returns the original Promise's value or rejection.
1Understanding Promise.finally()
Promise.finally() is the Promise equivalent of the finally block in try/catch. It receives no arguments (can't distinguish resolved from rejected) and runs cleanup code like hiding loading spinners, releasing resources, or resetting state. It returns the original Promise's value or rejection.
finally() is transparent — it passes through the resolved value or rejection without altering it (unless it throws or returns a rejected Promise).
async function loadWithSpinner() {
showSpinner();
try {
const data = await fetchData();
renderData(data);
} catch (e) {
showError(e.message);
} finally {
hideSpinner(); // always hides
}
}
// Equivalent with Promise chain
fetchData()
.then(renderData)
.catch(e => showError(e.message))
.finally(hideSpinner);2Practical Example
Here is a real-world application of Promise.finally() showing how it is used in production JavaScript code.
// finally is transparent to values
Promise.resolve(42)
.finally(() => console.log('settled!'))
.then(v => console.log('value:', v));
// settled!
// value: 423Best Practices
Follow these guidelines when working with Promise.finally():
1. Use finally() for UI cleanup (spinners, disabled buttons)
2. Don't return values from finally — they're ignored for non-rejections
3. Use for resource cleanup in Promise chains
Tip: finally() is transparent — it passes through the resolved value or rejection without altering it (unless it throws or returns a rejected Promise).
async function loadWithSpinner() {
showSpinner();
try {
const data = await fetchData();
renderData(data);
} catch (e) {
showError(e.message);
} finally {
hideSpinner(); // always hides
}
}
// Equivalent with Promise chain
fetchData()
.then(renderData)
.catch(e => showError(e.message))
.finally(hideSpinner);