finally()

ES2018+

Attaches a callback that is invoked when the Promise is settled (fulfilled or rejected).

Syntax

promise.finally(onFinally)

Parameters

onFinally Function

A function called when the Promise is settled

Return Value

Promise

A new Promise

Examples

JavaScript
let isLoading = true;
Promise.resolve('data')
  .then(data => console.log(data))
  .finally(() => {
    isLoading = false;
    console.log('로딩 완료');
  });
Output:
// 'data' '로딩 완료'

📌 When to Use

Use finally() for cleanup operations like hiding loading spinners, closing connections, or releasing resources regardless of success or failure.

⚠️ Common Mistakes

Expecting finally() to receive the resolved value or error - it receives no arguments.

Using finally() to transform values - it passes through the original value/error.

✅ Best Practices

Use finally() for side effects like UI updates, not for transforming promise results.

Place finally() before the last catch() if you need cleanup even when catch recovers.

⚡ Performance Notes

finally() creates an additional promise in the chain. For performance-critical code, consider combining cleanup into existing then/catch handlers.

🌍 Real World Example

Loading State Manager

Manage loading indicators that must be hidden regardless of API call success or failure.

async function fetchWithLoading(url, loadingElement) {
  loadingElement.style.display = 'block';

  return fetch(url)
    .then(response => {
      if (!response.ok) throw new Error('Network error');
      return response.json();
    })
    .finally(() => {
      // Always hide loading, success or failure
      loadingElement.style.display = 'none';
      console.log('Loading complete');
    });
}

// Usage
const loader = document.getElementById('loader');
fetchWithLoading('/api/data', loader)
  .then(data => console.log('Success:', data))
  .catch(err => console.log('Error:', err.message));
// Loading is hidden in both cases

Related Methods