Widely availableRecommended for shared cleanup that must happen after both success and failure paths.

Overview

Promise.prototype.finally() runs after a Promise settles, regardless of whether it fulfilled or rejected. It is useful for cleanup, loading indicators, and common teardown work.

Browser support

Feature Desktop Mobile
Chrome
Edge
Firefox
Safari
Chrome Android
Safari iOS
63
18
58
11.1
63
11.3
1+Supported (version) Not supported Has note Sub-feature descriptions sourced from MDN Web Docs (CC BY-SA 2.5)

Syntax

JAVASCRIPT
showLoading();

fetch('/api/data')
  .then(response => response.json())
  .then(data => displayData(data))
  .catch(error => showError(error))
  .finally(() => hideLoading());

Live demo

ro-deingdisplay. Control

Success / failure to, last to ro-deing hidden to..

PreviewFullscreen

button. doublesubmitprevention

redegreeenabledization.. with ProcessingStart time to button disabledization, end time to finally.

PreviewFullscreen

rogoutput. commonization

Processing that end and showrog, complete to output..

PreviewFullscreen

Use cases

  • Resetting transient UI

    Hide spinners, re-enable buttons, or clear temporary state once an async action finishes.

  • Releasing resources

    Close connections, remove locks, or stop timers in one shared place instead of duplicating cleanup logic.

Cautions

  • finally does not receive the resolved value or rejection reason directly, so use then/catch for result-specific behavior.
  • Cleanup code inside finally should stay safe and predictable, because throwing there changes the resulting Promise state.

Accessibility

  • If loading UI is removed in finally, make sure the completion state is still announced or visible afterward.

Powered by web-features