How to use finally on promise with then and catch in Javascript?

JavaScript asynchronous programming uses promise objects that don't block execution but signal when operations complete. Promises can either resolve successfully or reject with an error. The finally() method executes cleanup code regardless of the promise outcome, similar to finally blocks in synchronous try-catch statements.

Syntax

promise
   .then(result => {
      // handle success
   })
   .catch(error => {
      // handle error
   })
   .finally(() => {
      // cleanup code - always runs
   })

Why Use finally()?

Without finally(), you need duplicate cleanup code in both then() and catch() blocks:

promise
   .then(result => {
      // handle success
      // cleanup resources (duplicated)
   })
   .catch(error => {
      // handle error  
      // cleanup resources (duplicated)
   })

The finally() method eliminates this duplication by providing a single place for cleanup code.

Example: Database Connection Management

Let's create a database connection example that demonstrates proper resource cleanup:

class Connection {
   run(query) {
      if (query !== 'Add' && query !== 'Modify' && query !== 'Remove') {
         throw new Error(`Invalid query: ${query}`);
      }
      console.log(`Running query: ${query}`);
      return this;
   }

   terminate() {
      console.log('Terminating connection');
   }
}

const success = true;
function connect() {
   return new Promise((resolve, reject) => {
      if (success) {
         resolve(new Connection());
      } else {
         reject('Connection failed');
      }
   });
}

let globalConnection;

connect()
   .then(connection => {
      globalConnection = connection;
      return globalConnection.run('Add');
   })
   .then(connection => {
      return connection.run('Remove');
   })
   .then(connection => {
      return connection.run('Invalid'); // This will throw an error
   })
   .catch(error => {
      console.log('Error caught:', error.message);
   })
   .finally(() => {
      if (globalConnection) {
         globalConnection.terminate();
      }
   });
Running query: Add
Running query: Remove
Error caught: Invalid query: Invalid
Terminating connection

Key Points

  • finally() executes after both successful and failed promises
  • It's perfect for cleanup tasks like closing connections or freeing resources
  • The finally() callback receives no arguments
  • It was introduced in ES2018
  • The method always runs, even if previous then() or catch() throw errors

Multiple finally() Blocks

You can chain multiple finally() blocks, and they'll execute in order:

Promise.resolve('Success')
   .then(result => {
      console.log('Then:', result);
   })
   .finally(() => {
      console.log('First finally');
   })
   .finally(() => {
      console.log('Second finally');
   });
Then: Success
First finally
Second finally

Conclusion

The finally() method provides a clean way to handle cleanup tasks in promise chains. Use it for resource management, logging, or any code that must run regardless of promise outcome.

Arnab Chakraborty
Arnab Chakraborty

Corporate Trainer

Updated on: 2026-03-15T23:18:59+05:30

2K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements