instance
.finally()
Runs a callback after the promise settles regardless of outcome, without changing the resolved value or rejection reason. Ideal for cleanup like hiding spinners or closing connections.
promise.finally(onFinally) Parameters
| Parameter | Purpose |
|---|---|
| onFinally() | Called with NO arguments — you don't know success vs failure |
| pass-through | Returned value is IGNORED; the outer promise keeps the original settlement |
| throws propagate | If onFinally throws or returns a rejected promise, the outer chain rejects with that reason |
Examples
showSpinner();
fetchData()
.then(render)
.catch(showError)
.finally(() => hideSpinner()); Spinner is always hidden, whether fetchData resolved or rejected.
Promise.resolve('ok')
.finally(() => 'ignored')
.then(v => console.log(v)); // 'ok' The return value of .finally does not replace the resolved value.
Promise.resolve('ok')
.finally(() => { throw new Error('cleanup failed'); })
.catch(e => console.log(e.message)); // 'cleanup failed' Throwing in .finally does hijack the chain into rejection.
Gotcha
.finally receives no arguments — you can't tell success from failure inside it. Its return value is dropped unless it's a rejected promise or the callback throws.
Related
.then()
Registers callbacks for the fulfillment (and optionally rejection) of a promise and returns a new promise chained to the callback's return value. Returning a value fulfills the next promise; throwing or returning a rejected promise rejects it.
.catch()
Attaches a rejection handler to a promise chain, equivalent to .then(undefined, onRejected). Returns a new promise that fulfills with the handler's return value, letting you recover from errors.
try / catch with await
Since await throws when the awaited promise rejects, standard try/catch is the idiomatic way to handle async errors inside an async function. A finally block runs on both success and failure paths.
← All JS Promise reference · async/await vs promises vs callbacks