1. ホーム
  2. 記事一覧
  3. JavaScriptの基礎、Promiseを理解しよう

2024.09.22

JavaScriptの基礎、Promiseを理解しよう

はじめに

JavaScriptを学んでいると、「Promise」という言葉を耳にすることがあるかもしれません。Promiseは非同期処理に使われるとよく聞きくけど「実際に何をしているのか分からない…」「そもそもPromiseって何?」「開発でどうやって使うの?」と、疑問に思ったことはありませんか?Promiseが何をするものなのかイメージがつかないまま、学習を進めている方もいるかもしれません。

この記事では、そんな疑問を解消し、初めての方でもPromiseがどういうものかを理解できるように、具体的な使い方をわかりやすく解説します。Promiseの仕組みを理解すると、非同期処理で取得したデータをどう扱えばよいかが見えてきて、スムーズにコードを書けるようになります。基本をしっかり学ぶことで、JavaScript全体の理解が深まり、学習効率も上がるはずです。さっそく一緒にPromiseを学んでいきましょう。

この記事について

目的

  • Promiseの基礎を理解する
  • Promiseを使えるようになる

対象者

  • JavaScriptを学び始めたばかりの方
  • 非同期処理に興味がある方

JavaScriptの基本について

この記事では、JavaScriptの基礎的な部分には詳しく触れていません。JavaScriptの基礎を学びたい方は、以下の記事をぜひご覧ください。

https://envader.plus/article/331

Promiseとは

**Promiseは、JavaScriptで非同期処理の状態や結果を表すオブジェクトです。**非同期処理を行う関数は、処理の結果を表すPromiseオブジェクトを返します。このPromiseを使って、非同期処理が完了した後に実行したい処理をあらかじめ指定することができます。Promiseは、非同期処理の結果が成功したか失敗したかに応じて、適切な後続の処理を実行します。

非同期処理とは、ある処理が終わるのを待たずに次の処理に進む動作のことを指します。サーバーからデータを取得するなど、時間のかかる処理を待っている間も、他のプログラムが進行できる仕組みです。

たとえば、Webサイトでデータを取得する場合、そのデータが返ってくるまで待つと他の操作がすべて止まってしまいます。非同期処理を使えば、データ取得を進めながら他の処理も同時に行うことができます。

しかし、非同期処理がいつ終わるかわからないため、その結果を使った次の処理をどう管理するかが課題となります。ここでPromiseが役立ちます。Promiseは、非同期処理が完了したら実行したい処理をあらかじめ指定しておける仕組みです。つまり、非同期処理の結果を待ってから、その結果に基づいて次の処理を行うことが容易になります。

Promiseの状態について

Promiseは、非同期処理が今どの状態にあるかを管理し、その状態に応じて適切な処理を行います。Promiseの状態は以下の3つに分けられます。

  • pending(保留中)

    非同期処理がまだ完了していない状態です。たとえば、サーバーにデータをリクエストした直後は結果が返ってきていないため、このpending状態になります。

  • fulfilled(成功)

    非同期処理が正常に完了し、結果が得られた状態です。サーバーからデータが正しく返ってきた場合、Promiseはfulfilled状態に変わり、その結果をもとに次の処理を実行します。

  • rejected(失敗)

    非同期処理が失敗した状態です。ネットワークエラーやデータ取得に失敗したときなどが該当します。この場合、Promiseはrejected状態に変わります。

状態の流れ

Promiseは、次の3つの状態を順にたどります。

まず、Promiseは作成された瞬間にpending状態となり、非同期処理がスタートします。この段階では、まだ結果がどうなるかは分かりません。しばらくして非同期処理が完了すると、Promiseは次のいずれかの状態に移行します。

  • 処理が成功した場合

    fulfilled状態に移行し、その時点で非同期処理の結果を使って次の処理が実行されます。

  • 処理が失敗した場合

    rejected状態に移行し、その時点でエラーメッセージを処理するなど、エラーに対する対応が実行されます。

たとえば、サーバーからデータを取得する場合、最初は結果を待っているpending状態となり、データが無事に取得できればfulfilled状態に、もし何か問題が起きた場合はrejected状態に変わります。Promiseの便利なところは、各状態に応じて、次に何をするか(成功時の処理やエラー処理)をあらかじめ設定できる点です。このようにして、Promiseは非同期処理を整理し、複雑な流れを分かりやすく管理する役割を果たします。

サーバーから非同期処理でデータを取得する方法については、以下の記事で紹介しています。Promiseの理解をさらに深めたい方は、ぜひご覧ください。

https://envader.plus/article/465

Promiseの使い方

Promiseは「非同期処理の結果を待ってから、その結果に基づいて次の処理を行うことが容易になる」ということを学びました。PromiseはJavaScriptのオブジェクトの一種です。このオブジェクトには、非同期処理の状態や結果を保持するプロパティがあり、さらにthencatchといったメソッドを使って、処理の流れを設定することができます。

実際にPromiseがどのように動作するのか、コード例を見て確認しましょう。以下は、Promiseを使って非同期処理の成功時と失敗時に、どのような処理を行うかを設定している基本的なコードです。

// Promiseの基本

const promise = new Promise(function (resolve, reject) {
  setTimeout(() => {
    resolve('次の処理に渡す値'); // 1秒後に処理が成功する
  }, 1000);
});

// 成功時の処理
promise
  .then(function (value) {
    console.log(value); // '次の処理に渡す値'が表示される
  })
  // 失敗時の処理
  .catch(function (error) {
    console.error(error); // エラーが発生した場合、エラーメッセージが表示される
  });

Promiseの作成

const promise = new Promise(function (resolve, reject) {
  setTimeout(() => {
    resolve('次の処理に渡す値'); // 1秒後に成功
  }, 1000);
});

この部分では、new Promiseを使って新しいPromiseオブジェクトを作成しています。引数としてresolverejectという2つの関数を受け取ります。この例では、1秒後に処理が成功するように設定されています(setTimeoutで非同期処理をシミュレートしています)。

  • resolve

    非同期処理が正常に完了したときに呼ばれます。今回の例では、1秒後にresolveが呼ばれて、Promiseは成功(fulfilled)状態に変わり、'次の処理に渡す値'という文字列が結果として渡されます。

  • reject

    非同期処理が失敗したときに呼び出される関数です。

Promiseの利用

// 成功時の処理
promise
  .then(function (value) {
    console.log(value); // 結果を表示
  })
  // 失敗時の処理
  .catch(function (error) {
    console.error(error); // エラーを表示
  });

この部分では、.then().catch()を使って、Promiseの成功時と失敗時の処理を定義しています。Promiseの状態が「成功(fulfilled)」または「失敗(rejected)」に変わると、それに応じて次の処理を実行します。

  • promise.then(function (value) { ... })

    Promiseが成功したときに実行されます。valueにはresolveで渡された値(ここでは'次の処理に渡す値')が入ります。

  • .catch(function (error) { ... })

    Promiseが失敗した場合に実行され、errorにはエラー情報が入ります。

このコードを通じて理解しておきたいポイント

  • Promiseの基本的な構造と使い方

    Promiseは、非同期処理の結果を管理する仕組みです。このコードでは、Promiseの作成から、成功時・失敗時の結果処理までの一連の流れを学べます。Promiseオブジェクトは、resolveで成功を、rejectで失敗を表し、.then().catch()で結果を処理します。Promiseの構造は、非同期処理を整理し、コードを読みやすくします。

  • 非同期処理の管理

    Promiseを使うことで、非同期処理の成功時と失敗時の処理をそれぞれ設定できます。この例では、1秒後にresolveが呼ばれて成功し、.then()で結果が処理されます。また、失敗した場合はrejectが呼ばれ、.catch()でエラーメッセージが表示されます。非同期処理の流れを理解し、適切に管理することが重要なポイントです。

Promiseを使ってみよう

Promiseの流れや、成功・失敗時の結果をどう処理するかを学びました。このセクションでは、実際にPromiseを使ってコードを書いて、ハンズオン形式で理解を深めましょう。

今回のハンズオンでは、JSONPlaceholderというAPIサービスを利用します。JSONPlaceholderは、開発者がAPIを使ってデータのやり取りを練習できる、無料のオンラインモックAPIサービスです。

さらに、ブラウザ上で直接コードを試したい方には以下のサイトをおすすめします。フロントエンド技術の環境構築が不要で、すぐにPromiseのコードを実行できます。

Promiseを使用してデータを取得するコードの作成

今回のハンズオンでは以下のファイルを編集して、Promiseを作成してJSONPlaceholderからデータを取得します。

  • index.html
  • main.js

index.htmlの内容は以下の通りです。ここで、main.jsファイルを読み込みます。

<!-- index.html -->

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Promise</title>
  </head>
  <body>
	  <!-- main.jsファイルを読み込み -->
    <script type="module" src="/main.js"></script>
  </body>
</html>

次に、main.jsでPromiseを使ってデータを取得するコードを書きます。Promiseを使って非同期処理を行い、APIからデータを取得する関数を定義します。

// main.js

// Promiseを使ってデータを取得
function fetchPostsWithPromise() {
  return new Promise((resolve, reject) => {
    // fetch()を使ってデータを取得
    fetch('https://jsonplaceholder.typicode.com/posts')
      .then(response => {
        // レスポンスがOKか確認
        if (!response.ok) {
          reject('データの取得に失敗しました');
        }
        // レスポンスをJSONに変換
        return response.json();
      })
      .then(data => {
        // データ取得に成功したらresolveでデータを返す
        resolve(data);
      })
      .catch(error => {
        // エラーが発生した場合、rejectでエラーメッセージを返す
        reject('ネットワークエラーが発生しました');
      });
  });
}

// Promiseの使い方
fetchPostsWithPromise()
  .then(posts => {
    // 成功時の処理
    console.log('取得した投稿:', posts);
  })
  .catch(error => {
    // 失敗時の処理
    console.error('エラー:', error);
  });

コードを編集後、index.htmlをブラウザで開き、開発者ツールのConsoleを確認します。以下のようにpostsデータがConsoleに表示がされていれば、データ取得が成功したことになります。

コードの解説

今回のハンズオンでは新しくPromiseを作成し、FetchAPIを使用してJSONPlaceholderからデータを取得しました。Promiseの作成方法とコード内容の解説は前のセクションで行っていますので、データの取得部分のみを説明します。

  • fetchを使って非同期にリクエストを送信

    fetch('https://jsonplaceholder.typicode.com/posts')

    fetch()は非同期にリクエストを送信し、サーバーからのレスポンスをPromiseで返します。このコードでは、JSONPlaceholder APIの/postsエンドポイントから投稿データを取得しています。

  • レスポンスの処理

    .then(response => {
      // レスポンスがOKか確認
      if (!response.ok) {
        reject('データの取得に失敗しました');
      }
      // レスポンスをJSONに変換
      return response.json();
    })
    .then(data => {
      // データ取得に成功したらresolveでデータを返す
      resolve(data);
    })
    .catch(error => {
      // エラーが発生した場合、rejectでエラーメッセージを返す
      reject('ネットワークエラーが発生しました');
    });

    then()でレスポンスが正常かどうかを確認し、問題があればreject()を呼んでエラー処理を行います。成功時には、レスポンスデータをJSON形式に変換して次のthen()に渡します。catch()では、ネットワークエラーなどに対応します。

このハンズオンでは、Promiseを使って非同期処理を整理し、APIからデータを取得する流れを学ぶことができます。resolveで成功時の処理を行い、rejectで失敗時のエラーハンドリングを適切に行うことがポイントです。Promiseを使うことで、非同期処理の成功と失敗を簡単に管理できることがわかりました。

この記事で学んだこと

ここまで、Promiseの基本について学んできました。簡単に振り返りましょう。

Promiseは、JavaScriptで非同期処理の状態や結果を表すオブジェクトです。 非同期処理を行う関数は、処理の結果を表すPromiseオブジェクトを返します。このPromiseを使って、非同期処理が完了した後に実行したい処理をあらかじめ指定することができます。

Promiseは「pending(保留中)」の状態から始まり、処理が成功すれば「fulfilled(成功)」に、失敗すれば「rejected(失敗)」に変わります。Promiseを使うことで、非同期処理が成功した場合の次の処理や、失敗時のエラーハンドリングを簡単に設定できます。Promiseは非同期処理の結果を待ってから、その結果に基づいて次の処理を行うことを容易にします。

Promiseを理解することは、JavaScriptの非同期処理を扱う上で非常に重要です。今回の記事やハンズオンを通じて、Promiseの基本的な使い方やその便利さを実感していただければと思います。

参考資料

以下のリンクは、この記事で説明した手順や概念に関連する参考資料です。より詳しく学びたい方は、ぜひご参照ください。

【番外編】USBも知らなかった私が独学でプログラミングを勉強してGAFAに入社するまでの話

IT未経験者必見 USBも知らなかった私が独学でプログラミングを勉強してGAFAに入社するまでの話

プログラミング塾に半年通えば、一人前になれると思っているあなた。それ、勘違いですよ。「なぜ間違いなの?」「正しい勉強法とは何なの?」ITを学び始める全ての人に知って欲しい。そう思って書きました。是非読んでみてください。

「フリーランスエンジニア」

近年やっと世間に浸透した言葉だ。ひと昔まえ、終身雇用は当たり前で、大企業に就職することは一種のステータスだった。しかし、そんな時代も終わり「優秀な人材は転職する」ことが当たり前の時代となる。フリーランスエンジニアに高価値が付く現在、ネットを見ると「未経験でも年収400万以上」などと書いてある。これに釣られて、多くの人がフリーランスになろうとITの世界に入ってきている。私もその中の1人だ。数年前、USBも知らない状態からITの世界に没入し、そこから約2年間、毎日勉学を行なった。他人の何十倍も努力した。そして、企業研修やIT塾で数多くの受講生の指導経験も得た。そこで私は、伸びるエンジニアとそうでないエンジニアをたくさん見てきた。そして、稼げるエンジニア、稼げないエンジニアを見てきた。

「成功する人とそうでない人の違いは何か?」

私が出した答えは、「量産型エンジニアか否か」である。今のエンジニア市場には、量産型エンジニアが溢れている!!ここでの量産型エンジニアの定義は以下の通りである。

比較的簡単に学習可能なWebフレームワーク(WordPress, Rails)やPython等の知識はあるが、ITの基本概念を理解していないため、単調な作業しかこなすことができないエンジニアのこと。

多くの人がフリーランスエンジニアを目指す時代に中途半端な知識や技術力でこの世界に飛び込むと返って過酷な労働条件で働くことになる。そこで、エンジニアを目指すあなたがどう学習していくべきかを私の経験を交えて書こうと思った。続きはこちらから、、、、

note記事3000いいね超えの殿堂記事 今すぐ読む

エンベーダー編集部

エンベーダーは、ITスクールRareTECHのインフラ学習教材として誕生しました。 「遊びながらインフラエンジニアへ」をコンセプトに、インフラへの学習ハードルを下げるツールとして運営されています。

RareTECH 無料体験授業開催中! オンラインにて実施中! Top10%のエンジニアになる秘訣を伝授します! RareTECH講師への質疑応答可

関連記事

2020.02.25

完全未経験からエンジニアを目指す爆速勉強法

USBも知らなかった私が独学でプログラミングを勉強してGAFAに入社するまでの話

  • キャリア・学習法
  • エンジニア

2024.09.26

JavaScriptの基礎 async/awaitを理解しよう

非同期処理を扱う方法はJavaScriptにいくつかありますが、今ではasync/awaitが主流となっています。async/awaitは、Promiseよりもシンプルで、コードの見通しが良くなるという利点があります。

  • JavaScript
  • フロントエンド

2024.03.30

フロントエンジニアを目指す初心者向け TypeScriptの基礎を解説

この記事の目的は、初心者にもわかりやすくTypeScriptの基礎から実践的な使い方までを解説し、TypeScriptを使ったコーディングに必要な知識を身につけてもらうことです。

  • エンジニア
  • フロントエンド
  • JavaScript
  • TypeScript

2024.09.09

JavaScriptの基本、オブジェクトを理解しよう

JavaScriptを学習する中で、よく目にするオブジェクトについて、少しわかりにくいと感じることはありませんか?実は、JavaScriptのオブジェクトは単なるデータのまとまり以上に、プログラム全体で重要な役割を果たしています。オブジェクトを正しく理解できれば、データの操作や管理がスムーズになり、より効率的にコードを書けるようになります。

  • JavaScript
  • フロントエンド