JavaScriptのPromiseとは?

JavaScript Promiseとは?

JavaScript Promiseとは?

JavaScriptにおいて、非同期処理はウェブ開発において欠かせない要素です。ページの読み込みをブロックすることなく、スムーズなユーザー体験を提供するために、非同期処理は多用されます。しかし、非同期処理は、その性質上、コードの実行順序が複雑になりがちで、可読性や保守性の低下を招く可能性があります。そこで登場するのが「Promise」です。

Promiseは、非同期処理の結果を表現するためのオブジェクトであり、非同期処理の成功または失敗といった状態とその結果をカプセル化します。これにより、非同期処理をより直感的で扱いやすい形にすることができます。

Promiseの状態

Promiseは、以下の3つの状態のいずれかをとります。

状態 説明
Pending(保留) Promiseが作成された初期状態。非同期処理はまだ完了していません。
Fulfilled(履行済み) 非同期処理が成功し、結果が利用可能になった状態。
Rejected(拒否済み) 非同期処理が失敗し、エラーが発生した状態。

Promiseは一度状態が変わると、その後再び変わることはありません。これは、非同期処理の結果が確定したら、その後変更されることはなく、常に一貫した結果を返すことを保証します。

Promiseの基本的な使い方

Promiseオブジェクトは、Promiseコンストラクタを使って作成します。コンストラクタには、実行する非同期処理を表す関数を渡します。この関数は、resolverejectという2つの引数を受け取ります。

const myPromise = new Promise((resolve, reject) => {
  // 非同期処理を実行する
  if (/* 非同期処理が成功した場合 */) {
    resolve('成功時の結果'); // Promiseの状態をFulfilledにする
  } else {
    reject('失敗時のエラー'); // Promiseの状態をRejectedにする
  }
});

resolve関数は、非同期処理が成功した場合に呼び出され、Promiseの状態を"Fulfilled"にします。また、resolve関数に渡した値は、Promiseの結果として取得できます。

reject関数は、非同期処理が失敗した場合に呼び出され、Promiseの状態を"Rejected"にします。reject関数に渡した値は、Promiseのエラー情報として取得できます。

Promiseのメソッド

then()

Promiseの結果を受け取るには、then()メソッドを使用します。then()メソッドは、Promiseの状態が"Fulfilled"になったときに呼び出されるコールバック関数を引数として受け取ります。

myPromise.then((result) => {
  console.log(result); // '成功時の結果' が出力される
});

catch()

Promiseが"Rejected"状態になった場合のエラー処理には、catch()メソッドを使用します。catch()メソッドは、Promiseの状態が"Rejected"になったときに呼び出されるコールバック関数を引数として受け取ります。

myPromise.catch((error) => {
  console.error(error); // '失敗時のエラー' が出力される
});

Promiseの活用例

Promiseは、非同期処理を伴う様々な状況で役立ちます。例えば、

  • Ajaxリクエストの実行
  • setTimeoutなどのタイマー処理
  • 画像の読み込み

以下は、Ajaxリクエストを実行する例です。

function fetchData(url) {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    xhr.open('GET', url);
    xhr.onload = () => {
      if (xhr.status === 200) {
        resolve(xhr.responseText);
      } else {
        reject(new Error(`Request failed with status ${xhr.status}`));
      }
    };
    xhr.onerror = () => {
      reject(new Error('Request failed'));
    };
    xhr.send();
  });
}

fetchData('https://example.com/api/data')
  .then((data) => {
    console.log(data); // 取得したデータ
  })
  .catch((error) => {
    console.error(error); // エラー情報
  });

参考文献

Q&A

Q1: Promiseとコールバック関数の違いは何ですか?

A1: コールバック関数は非同期処理が完了した際に呼び出される関数のことを指し、Promiseは非同期処理の状態とその結果を表現するオブジェクトです。Promiseを使うことで、コールバック関数をネストさせることなく、非同期処理を連鎖的に記述できるようになり、コードの可読性が向上します。

Q2: Promise.all()は何をするものですか?

A2: Promise.all()は、複数のPromiseを受け取り、全てのPromiseが"Fulfilled"状態になったときに、それぞれのPromiseの結果を配列として返すPromiseを返します。一つでも"Rejected"状態になった場合は、そのエラーが即座に伝播します。

Q3: async/awaitとPromiseの関係を教えてください。

A3: async/awaitは、Promiseをより直感的に扱えるようにする構文です。asyncキーワードで定義された関数はPromiseを返し、awaitキーワードを使うことで、Promiseの結果を同期的に取得できます。

その他の参考記事:JavaScript の約束