名古屋出身ソフトウェアエンジニアのブログ

JavaScript: コールバック関数を Promise に変換する

公開:
更新:

WEB フロントエンドの JavaScript 開発では、非同期の操作を行う必要が多々あります。コールバック関数はそれらシナリオで頻繁に使われますが、複雑になりがちで、複数のコールバック関数が絡まる問題、通称「コールバック地獄」と呼ばれる状況を生成します。

JavaScript は ES6 で Promise を導入し、ES7 では async/await 構文を提供しました。これらの新機能により、非同期コードをより一貫して読みやすい形式で表現することが可能です。この記事ではコールバック関数を Promise に変える方法を示します。

基本的な考え方は、新しい Promise を作成するとき、resolve 関数を対象コールバック関数の中で呼び出すことです。コールバックの中で resolve が呼び出された時、Promise はその値と共に解決されます。

以下は DOMContentLoaded イベントを Promise で包む例です。

const contentLoadedPromise = new Promise((resolve) => {
  // より汎用にする為、読み込みタイミングを考慮し、readyState をチェックする
  if (document.readyState === "loading") {
    // DOMContentLoaded イベントが発生した時、Promise を解決するように設定します
    document.addEventListener("DOMContentLoaded", () => resolve());
  } else {
    // すでにページが読み込まれている場合、直ちに Promise を解決します
    resolve();
  }
});

次に示すように、await キーワードを使用して Promise が解決するのを待ちます。await キーワードは Promise が解決されるまで処理をブロックし、Promise が解決したらその値を返します。これにより、DOM が完全に読み込まれるまで待つことができます。

await contentLoadedPromise; // DOMの読み込み完了を待つ
const element = document.getElementById("hoge"); // 要素を取得する

この変換により、コールバック処理の中に深くネストしたロジックを使わずに、処理内容を綺麗に整理できます。