Finally performs cleanup and normally preserves the previous result. A thrown error or rejected promise in cleanup replaces the earlier outcome.
Step-by-step walkthrough
Step 1: Separate result work from cleanup
Successful transformation belongs in then or after await. Cleanup belongs in finally when it must happen for success and failure. Keep those responsibilities distinct so a returned data value is not confused with an ignored cleanup return value.
Step 2: Trace the preserved outcome
An ordinary finally callback passes through the previous fulfillment value or rejection reason. Throwing or returning a rejected promise from cleanup changes the chain to that new failure. This is useful to understand when a cleanup error masks the original problem.
Step 3: Protect the primary failure
Cleanup itself should have an intentional failure policy. Record a secondary release error without losing the original operation error when that is the desired contract. Also ensure cleanup belongs to the current resource owner rather than clearing another request’s state.
Worked scenario
A spinner cleanup leaves the response intact unless hiding the spinner itself throws.
const value = await Promise.resolve(7).finally(() => 99);
console.log(value); // 7
try {
await Promise.reject(new Error('request failed'))
.finally(() => { throw new Error('cleanup failed'); });
} catch (error) {
console.log(error.message); // cleanup failed
}Walk through the example
The first cleanup return does not replace seven. The second cleanup throws, so that error becomes the chain’s rejection. A spinner callback that cannot fail is simple; resource cleanup that can fail needs a deliberate way to retain both the operation failure and release failure for diagnostics.
Common mistake
Returning a normal value from finally does not transform the result. Catch without rethrowing may turn failure into success.
Verify the behavior
Test fulfilled and rejected inputs, synchronous cleanup throws and asynchronous cleanup rejection. For UI cleanup, overlap two operations and verify an obsolete operation cannot clear the current operation’s loading state or resource reference.
Interview exercise
Separate transformation from cleanup.
Answer and reasoning
Transform in then or after await, release resources in finally, and keep cleanup from obscuring the primary error.
Follow-up discussion
Why not return the transformed response in finally? Its normal return is ignored for that purpose. Does finally mean success? No: it runs after either outcome and normally preserves that outcome. Observe success or failure through the appropriate continuation.
Continue learning
Compare the scenario with the JavaScript interview questions and test your understanding with the JavaScript MCQs. For terminology and implementation details, consult the reference material.