【2026年版】JavaScriptのPromise・async/await完全解説|非同期処理をマスターしてコードの質を上げる

JavaScriptの非同期処理は、現代のWeb開発において欠かせない技術です。本記事では、Promise・async/awaitの基礎から実践的な活用方法まで徹底解説します。APIリクエスト、ファイル操作、並列処理など実際のユースケースを通じて、あなたのJavaScriptスキルを次のレベルへ引き上げましょう。

JavaScriptの非同期処理とは何か

JavaScriptはシングルスレッドで動作する言語です。つまり、一度に1つの処理しか実行できません。しかし、Webアプリケーションでは、APIからのデータ取得やファイルの読み込みなど、時間のかかる処理を効率よく扱う必要があります。これを解決するのが非同期処理です。

非同期処理により、時間のかかる処理をバックグラウンドで実行しながら、メインスレッドの処理を続けることができます。従来のコールバック関数から進化したPromise、そしてasync/awaitが現代のJavaScript開発の標準となっています。

Promiseの基礎を理解する

Promiseは非同期処理の「約束」を表すオブジェクトです。3つの状態があります:pending(待機中)fulfilled(成功)rejected(失敗)

// Promiseの基本的な作り方
const fetchData = new Promise((resolve, reject) => {
  setTimeout(() => {
    const success = true;
    if (success) {
      resolve({ data: 'ユーザー情報取得成功', userId: 123 });
    } else {
      reject(new Error('データ取得に失敗しました'));
    }
  }, 1000);
});

fetchData
  .then(result => console.log('成功:', result.data))
  .catch(error => console.error('エラー:', error.message))
  .finally(() => console.log('処理完了'));

async/awaitで読みやすいコードを書く

async/awaitはPromiseをより直感的に書くための構文糖衣(シンタックスシュガー)です。非同期コードを同期コードのように記述できるため、可読性が大幅に向上します。

async function getUserData(userId) {
  try {
    const response = await fetch(`https://api.example.com/users/${userId}`);
    if (!response.ok) throw new Error(`HTTPエラー: ${response.status}`);
    const user = await response.json();
    return user;
  } catch (error) {
    console.error('ユーザーデータの取得に失敗:', error.message);
    throw error;
  }
}

Promise.allで並列処理を最適化する

複数の非同期処理を同時に実行したい場合、Promise.all()が非常に有効です。順番に処理するより大幅に高速化できます。

// 並列処理(速い)
async function fetchParallel() {
  const [user, posts, comments] = await Promise.all([
    fetchUser(1),
    fetchPosts(1),
    fetchComments(1)
  ]);
  return { user, posts, comments };
}

// Promise.allSettledで一部失敗してもOK
const results = await Promise.allSettled([
  fetchUser(1),
  fetchPosts(1),
  fetchComments(999) // エラーになるが全体は続行
]);
results.forEach((result, index) => {
  if (result.status === 'fulfilled') {
    console.log('成功:', result.value);
  } else {
    console.log('失敗:', result.reason);
  }
});

エラーハンドリングのベストプラクティス

非同期処理のエラーハンドリングは、アプリケーションの安定性に直結します。カスタムエラークラスとtry/catchを適切に組み合わせましょう。

class ApiError extends Error {
  constructor(message, statusCode) {
    super(message);
    this.name = 'ApiError';
    this.statusCode = statusCode;
  }
}

async function fetchUserSafely(userId) {
  try {
    const response = await fetch(`/api/users/${userId}`);
    if (response.status === 404) throw new ApiError('ユーザーが見つかりません', 404);
    if (!response.ok) throw new ApiError('サーバーエラー', response.status);
    return await response.json();
  } catch (error) {
    if (error instanceof ApiError) {
      console.error(`APIエラー [${error.statusCode}]: ${error.message}`);
    } else if (error instanceof TypeError) {
      console.error('ネットワーク接続を確認してください');
    } else {
      console.error('予期しないエラー:', error);
    }
    return null;
  }
}

まとめ:非同期処理マスターへのロードマップ

  • Step 1:コールバック関数の仕組みを理解する
  • Step 2:Promiseの3つの状態(pending/fulfilled/rejected)を理解する
  • Step 3:.then()/.catch()/.finally()でPromiseチェーンを書く
  • Step 4:async/awaitで同期的に見えるコードを書く
  • Step 5:Promise.all()で並列処理を最適化する
  • Step 6:TypeScriptと組み合わせて型安全な非同期処理を書く

非同期処理の理解は、モダンJavaScript開発の核心です。ReactやVue.jsなどのフレームワークを使う際も、この知識は必ず役立ちます。ぜひ実際にコードを書いて、非同期処理をマスターしてください。

投稿者 kasata

IT企業でエンジニアとして勤務後、テクノロジー情報メディア「Tech Athletes(テック・アスリート)」を運営。プログラミング、クラウドインフラ(AWS/GCP/Azure)、AI活用、Webサービス開発を専門とする。エンジニア・ビジネスパーソン向けに、実際に使ってみた経験をもとに信頼できる技術情報を発信中。資格:AWS認定ソリューションアーキテクト、Python 3 エンジニア認定試験合格。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です