JavaScriptでPromiseを使用する際、処理の成功・失敗に関わらず必ず実行したい処理がある場合があります。そんなときに便利なのが`finally()`メソッドです。この記事では、`finally()`メソッドの基本的な使い方から実践的な例まで解説します。

finally()メソッドとは

`finally()`メソッドは、Promiseチェーンの最後に追加できるメソッドで、Promiseの成功(resolve)や失敗(reject)に関係なく、必ず実行される処理を定義できます。

基本的な構文

promise
  .then(result => {
    // 成功時の処理
  })
  .catch(error => {
    // 失敗時の処理
  })
  .finally(() => {
    // 必ず実行される処理
  });

実践的な使用例

ローディング表示の制御

const loadingElement = document.getElementById('loading');

// ローディング表示を開始
loadingElement.style.display = 'block';

fetchData()
  .then(data => {
    // データ取得成功時の処理
    console.log(data);
  })
  .catch(error => {
    // エラー発生時の処理
    console.error('エラーが発生しました:', error);
  })
  .finally(() => {
    // 成功・失敗に関わらずローディング表示を終了
    loadingElement.style.display = 'none';
  });

データベース接続の後処理

let connection;

connectDatabase()
  .then(conn => {
    connection = conn;
    return performDatabaseOperation();
  })
  .catch(error => {
    console.error('データベース操作エラー:', error);
  })
  .finally(() => {
    // 接続のクローズを保証
    if (connection) {
      connection.close();
    }
  });

finally()メソッドの特徴

1. 戻り値は無視される

2. エラーがスローされた場合は、次のcatchブロックに伝播する

3. 非同期処理も実行可能

エラーハンドリングの例

async function processData() {
  try {
    const result = await fetch('https://api.example.com/data');
    const data = await result.json();
    return data;
  } catch (error) {
    throw new Error('データの取得に失敗しました');
  } finally {
    console.log('処理が完了しました');
  }
}

注意点

  • `finally()`内でエラーが発生した場合、新しいPromiseのrejectとして扱われる
  • `finally()`は値を返さないため、チェーンの中間で使用する場合は注意が必要
  • IE11など一部の古いブラウザではサポートされていない

まとめ

`finally()`メソッドは、Promiseの処理結果に関わらず実行すべき後処理を簡潔に記述できる便利な機能です。特に、リソースの解放やUIの状態管理など、確実に実行する必要がある処理に適しています。適切に使用することで、よりメンテナンス性の高いコードを書くことができます。