JavaScriptのPromiseをわかりやすく解説!初心者向け入門ガイド

JavaScriptを学習していると、「非同期処理」という言葉に出会うことがよくあります。特に、APIからデータを取得したり、時間のかかる処理を効率的に実行したい場合、非同期処理の仕組みを理解することが重要になります。その中で頻繁に使われるのが「Promise(プロミス)」です。

しかし、「Promiseってなんだか難しそう…」「コールバックと何が違うの?」と感じる方も多いでしょう。そこで本記事では、Promiseの基本概念から、実際の使い方、そしてasync/awaitとの違いまでを初心者向けにわかりやすく解説します。


1. Promiseとは?

Promiseの定義

Promiseとは、JavaScriptにおける非同期処理を管理するためのオブジェクトです。非同期処理とは、処理が完了する前に次の処理が実行される仕組みのことを指します。

▼Promise – JavaScript – MDN Web Docs
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise

なぜPromiseが必要なのか?

従来、JavaScriptでは非同期処理をコールバック関数で制御していました。しかし、コールバックを入れ子にしていくと「コールバック地獄(Callback Hell)」と呼ばれるコードの可読性が低い状態になってしまいます。

コールバック地獄の例:

setTimeout(() => {
  console.log("1秒後に実行");
  setTimeout(() => {
    console.log("さらに1秒後に実行");
    setTimeout(() => {
      console.log("さらに1秒後に実行");
    }, 1000);
  }, 1000);
}, 1000);

このようなネストが深いコードは可読性が悪く、バグの温床になります。これを解決するためにPromiseが登場しました。

Promiseの3つの状態

Promiseには以下の3つの状態があります。

  • pending(未決):処理が完了していない状態
  • fulfilled(成功):処理が成功した状態
  • rejected(失敗):処理が失敗した状態

Promiseはこれらの状態を管理し、成功時・失敗時に適切な処理を実行することができます。


2. Promiseの基本構文と使い方

Promiseを使うためには、まずnew Promise()を使ってPromiseオブジェクトを作成します。基本的な構文は以下のようになります。

const myPromise = new Promise((resolve, reject) => {
  // 非同期処理
  setTimeout(() => {
    let success = true;
    if (success) {
      resolve("処理が成功しました");
    } else {
      reject("エラーが発生しました");
    }
  }, 2000);
});

このPromiseは、2秒後にresolveが呼ばれれば「処理が成功しました」となり、rejectが呼ばれれば「エラーが発生しました」となります。

then()とcatch()の使い方

Promiseは、.then().catch()を使って結果を受け取ることができます。

myPromise.then(result => {
  console.log(result); // 「処理が成功しました」
}).catch(error => {
  console.error(error); // 「エラーが発生しました」
});

.then()resolve()が呼ばれたときに実行され、.catch()reject()が呼ばれたときに実行されます。これにより、エラーハンドリングも簡単に行えます。


3. then, catch, finallyの違いと使い方

then()

  • then()は、Promiseが成功(fulfilled)したときに実行される関数を指定します。

catch()

  • catch()は、Promiseが失敗(rejected)したときに実行される関数を指定します。

finally()

  • finally()は、成功・失敗に関係なく、最後に必ず実行される関数を指定します。

例:

myPromise
  .then(result => {
    console.log("成功: " + result);
  })
  .catch(error => {
    console.error("失敗: " + error);
  })
  .finally(() => {
    console.log("処理が完了しました。");
  });

finally()は、後片付けやログ出力などに役立ちます。


4. async/awaitとの違いと使い分け

async/awaitとは?

async/awaitは、Promiseをより直感的に扱うための構文です。Promiseの.then().catch()を使わずに、同期処理のように非同期処理を書けるのが特徴です。

async/awaitの基本構文

async function fetchData() {
  try {
    let response = await fetch('<https://api.example.com/data>');
    let data = await response.json();
    console.log(data);
  } catch (error) {
    console.error("エラー発生", error);
  }
}

async/awaitとPromiseの違い

  • async/awaitの方がコードがシンプルで可読性が高い
  • async/awaittry...catchでエラーハンドリングがしやすい
  • Promiseの.then()と組み合わせて使うことも可能

async/awaitを使うことで、複雑な非同期処理をよりシンプルに記述できます。


5. まとめ

本記事では、JavaScriptのPromiseについて初心者向けにわかりやすく解説しました。

重要なポイントを振り返ると

  • Promiseは非同期処理を管理するためのオブジェクト
  • then(), catch(), finally()を活用することでエラーハンドリングが容易になる
  • async/awaitを使うとより直感的に非同期処理が書ける

Promiseを理解し使いこなせるようになると、API通信やタイマー処理などをよりスムーズに実装できるようになります。ぜひ実際にコードを書きながら学んでみてください!