プログラミング初心者のための入門ブログエンジニアが未来を切り開く。概念と操作の基礎この広告は、90日以上更新していないブログに表示しています。本日はJavaScriptのPromiseの操作とその概念について初学者様に解説致します。最後に前提の知識とスキルとして、少なくともES6の関数・高階関数・コールバック関数およびJavaScriptオブジェクトに精通している必要があります。上記を学び終えてない方は、以下で学習できますので参照ください。dev-k.hatenablog.comdev-k.hatenablog.comdev-k.hatenablog.com非同期関数JavaScriptにおいて非同期処理を行う際には、従来はコールバック関数を利用していました。JavaScriptにおいて関数が第一級オブジェクトであるため、コールバック関数を用いることができます。第一級オブジェクトとは、簡単に言えば変数に代入したり、引数や戻り値として扱うことができるオブジェクトのことです。JavaScriptにおいては、関数が第一級オブジェクトであるため、関数を引数として別の関数に渡すことができます。この特性を利用して、コールバック関数を実現しています。コールバック関数を不適切に扱うと、コードが読みにくくなる「コールバック地獄」や「スパゲッティコード」に陥ることがあります。これは、コールバック関数が入れ子になり、エラー処理が煩雑になることが原因です。そこで、ES6からはPromiseオブジェクトが導入され、非同期処理をより適切に扱うことができるようになりました。Promiseオブジェクトは、ネストされたコールバック関数を簡潔に書くことができ、エラー処理も明確に行えるため、コードの可読性が向上し、バグの発生を防ぐことができます。Hibbardによって呼ばれるようになったことが知られています。彼らはコンピュータサイエンスの教授であり、プログラミング言語を研究していました。約束とは、実際の生活での約束と同じように、将来何かをすることを保証するものです。JavaScriptでのPromiseも同じであり、約束の時間が来たときに解決されるか、または拒否されます。Promiseを使用すると、非同期のリクエストが完了するまでコードブロックの実行を延期できるため、他の操作を中断することなく実行し続けることができます。これにより、コールバック地獄を回避し、非同期関数を簡単にチェーンできるようになります。このようにPromiseは、操作の非同期結果を処理するために使用され、if文とは異なります。Promiseは将来使用できるデータを取得することを約束し、非同期関数の実行を遅延させることができます。重要な利点は、Promiseを使用することで、非同期関数をより簡単にチェーンできることです。これにより、コードの可読性が向上し、開発者がより生産的になることができます。Promiseの状態Promiseはオブジェクトであり、3つの状態が存在します。最初は「Pending」状態であり、Promiseが成功または失敗する前の初期状態となります。これは、作成されてから情報を受信するまでの待機時間を表します。次に、「Resolved」状態に移行します。これは、Promiseが成功し、処理が完了した状態を表します。サーバーからデータを受信し、正常に処理が完了した場合、Promiseはこの状態になります。情報の取得が失敗した場合は、「Rejected」状態に移行します。Promiseが失敗し、エラーがスローされます。この状態では、約束が果たせなかったことを示します。Promiseを使用して、サーバーからデータを要求する場合、Promiseオブジェクトは最初はPending状態となります。サーバーは、データを受信するまで保留状態「Pending」になります。その後、情報が正常に取得された場合はResolved状態に移行し、データを処理することができます。情報の取得に失敗した場合は、Rejected状態に移行し、エラーをスローします。これらの状態は非常に重要であり、Promiseの理解に必要不可欠です。これらの状態を理解した上で、Promiseオブジェクトを正しく作成することが重要です。Promiseの作成JavaScriptで非同期処理を実行する際にPromiseオブジェクトを使うことがあります。Promiseオブジェクトは、処理が成功したか失敗したかを返し、後続の処理を制御する機能を持っています。Promiseオブジェクトを作成するには、コンストラクターを使用します。Promise()でPromiseオブジェクトのインスタンスを作成します。}});Promiseオブジェクトは、2つの引数を持ちます。resolveは処理が成功した場合に呼び出され、rejectは処理が失敗した場合に呼び出されます。Promiseオブジェクトが作成された時点では、まだ処理が実行されていないため、状態は「Pending」になります。Promiseオブジェクトの状態が変化した時に、then()メソッドとcatch()メソッドを使って後続の処理を行います。});then()メソッドは、Promiseオブジェクトがresolveされたときに呼び出されます。catch()メソッドは、Promiseオブジェクトがrejectされたときに呼び出されます。このように、Promiseオブジェクトを使うことで、非同期処理の制御が簡単になります。CodePen.Promise条件をtrueからfalseにし、実行してみて下さい。情報は取得されず、rejectが呼び出され状態はRejectedに移行しcatch()が実行されエラー文を通知します。})Promiseは一度だけ解決または拒否できるため、上記は機能します。初回resolveまたはreject呼び出しは、Promiseの結果を決定し、別の要求が終了した後に戻ってくる要求によって引き起こされた、それ以降の呼び出しは無視されます。resolveとrejectは状態がPendingから移行されてしまったら、一度しか実行しません。他の例でも見てみましょう。JavaScriptのPromiseは、非同期操作を扱うためのオブジェクトであり、その操作が完了した場合に成功(resolve)または失敗(reject)として解決します。一度解決または拒否されると、その後の呼び出しは無視されます。夕食の約束を例にとると、Promiseを作成して夕食に行くことができるかどうかを判断します。このPromiseが実行されると、夕食に行くことができる場合にはresolveを、行けない場合にはrejectを呼び出して、その結果を提供します。それに基づいてPromiseの状態をPending状態からFulfilledまたはRejected状態に変更します。以下は、上記のPromiseをJavaScriptのコードとして示したものです。});上記のPromiseを呼び出すと、thenメソッドが成功した場合に実行され、catchメソッドが失敗した場合に実行されます。それぞれのメソッドの中に、Promiseの状態に基づいて処理するコードを記述します。});このように、Promiseは非同期操作の最終的な完了または失敗を表すオブジェクトであり、その状態に応じてthenメソッドとcatchメソッドで処理することができます。Promiseは、非同期処理をより簡単に扱うことができるようになりました。Promiseをチェーンする方法Promiseの最も重要な利点は、複数の依存する非同期操作を処理するためのチェーンを簡単に作成できることです。複数の非同期リクエストを順番に実行する必要がある場合、このチェーンは非常に役立ちます。最初のPromiseが解決または拒否された後、別のPromiseを作成し、これらのPromiseをチェーンすることで、新しいプロセスを開始することができます。Promiseは、then()メソッドを使用して、複数の処理を順番に実行することができます。JavaScriptのthen()メソッドは、Promiseオブジェクトにハンドラー関数を追加するために使用されます。.then()の結果は、ハンドラーチェーンを通過します。ハンドラーが値を返すと、それが次の.then()に繋がります。以下は、単純な乗算(掛け算)を.then()で繋げたチェーンの例です。CodePen.このように、Promiseの結果は.then()メソッドに渡すことができます。この.then()の方法は、一般的にPromiseチェーンと呼ばれます。注意点として、複数回.then()を呼び出した場合、チェーンにはなりません。6;});1つのPromiseに対して複数のハンドラーが存在する場合、これらは独立して実行されます。チェーンにはならないことに注意してください。Promiseを返すPromiseオブジェクトのthen()メソッドには、新しい値を返すことができ、これによって新しいPromiseオブジェクトが即座に解決されるようになります。"という値で解決します。その後、then()メソッドによって、前のPromiseオブジェクトが解決された結果を取得し、新しいPromiseオブジェクトを生成して返します。これによって、非同期処理をチェーン化することができます。"という値を表示する新しいPromiseオブジェクトを生成し、次のthen()メソッドに渡します。Taro."という値を表示する新しいPromiseオブジェクトを生成し、次のthen()メソッドに渡します。Taro."という値を表示することができます。CodePen.promiseのthenとfinallyの違いPromiseを学ぶ際に、必ず知る必要があるメソッドの1つがfinally()です。finally()メソッドは、ES2018で導入されました。Promiseが解決または拒否された場合、finally()メソッドで指定されたコールバック関数が呼び出されます。finally()メソッドはPromiseを返し、Promiseが正常に実行されたか、Promiseが処理された後に拒否されたかに関係なく、コードを実行する方法を提供します。以下はfinally()メソッドを使用した例です。上記のコードでは、Promiseが正常に処理されているため、finally()メソッドが成功時に実行されています。次に、失敗した場合を見てみましょう。CodePen.上記のコードでは、Promiseが失敗しているため、finally()メソッドが失敗時に実行されています。重要な点として、成功か失敗かにかかわらず、Promiseはfinally()メソッドを実行します。これは、Promiseチェーンでエラーのキャッチを延期して、他の場所でエラーを処理する必要がある場合に使用することができます。then()メソッドの代替としてfinally()メソッドを使用することは避けることをお勧めします。finally()メソッドは、タイムアウトのクリア、参照の無効化、UI状態のリセットなど、クリーンアップに使用することができます。});finally()メソッドは、他のメソッドと同様にコールバックを受け取りますが、Promiseが解決する値にはアクセスできません。そのため、値を変更することはできません。finally()メソッドはPromiseチェーンでエラーを処理するために使用されることはありません。代わりに、catch()メソッドを使用してエラーをキャッチすることが推奨されます。finally()メソッドは、Promiseが成功した場合でも失敗した場合でも実行され、そのため、Promiseの状態がどうであれ、最後に必ず実行されます。これは、Promiseチェーンのクリーンアップに役立ちます。ネットワークリクエストのタイムアウトをクリアする、参照を解放する、UI状態をリセットする、などのクリーンアップを行うことができます。finally()メソッドは、Promiseが成功または失敗した場合に実行されるため、Promiseチェーン内で使用することで、共通のクリーンアップ処理を一箇所にまとめることができます。console.log('データの取得が完了しました。});}この例では、fetch()メソッドを使用してデータを取得し、取得に成功した場合はJSONデータを返します。取得に失敗した場合はエラーをスローします。どちらの場合でも、finally()メソッドが実行され、データの取得が完了したことが確認できます。高度な複数のPromise処理Promiseコンストラクターオブジェクトには、非同期処理をより高度に制御するための様々なメソッドが含まれています。その中でも、単一や複数のPromise処理をする為のメソッドとして、Promise.all()、Promise.allSettled()、Promise.race()、Promise.any()があります。ここでは、Promise.all()メソッドについて詳しく説明します。Promise.all()メソッドは、引数に渡された複数のPromiseが全て解決(resolve)した時に、新たなPromiseを返します。この新たなPromiseは、全てのPromiseの値を配列にして解決され(resolve)ます。以下のようにPromise.all()を使用することで、3つの非同期処理を行い、それらが全て終了した時に結果をまとめて受け取ることができます。CodePen.Promise.all()は、非同期処理を同時に行うことで、複数の結果を効率的に取得することができます。Promise.all()は、全てのPromiseが解決された場合にのみ解決されるため、どれか一つでも失敗した場合はエラーとなります。これを使えば、複数のAPIからデータを取得し、それらをまとめて表示するなど、様々な用途に応用することができます。JavaScriptのFetchAPIを使用したPromiseベースのHTTPリクエスト当記事ではPromiseを作成し、結果を処理しました。Promiseは、非同期の操作が完了した後に結果を返すためのオブジェクトです。APIを使用すると、HTTPリクエストを行った後にPromiseオブジェクトが返されます。以下のコードを見てみましょう。上記のコードでは、fetch()メソッドを使用して、「https://jsonplaceholder.typicode.com/users」からのGETリクエストを実行します。リクエストが成功した場合、responseオブジェクトが返されます。Promiseチェーンの最初のthen()メソッドでは、response.okをチェックして、レスポンスが正常な場合はそのままresponseオブジェクトを返し、失敗した場合はエラーを処理します。次に、response.json()メソッドを使用して、JSONデータを取得し、then()メソッドでそのデータを処理しています。最後に、JSONデータをコンソールに出力しています。このように、Promiseを使用すると、非同期処理を行う際にコールバック地獄を避けることができます。Promiseチェーンを使用すると、処理が一連の手順に分かれ、可読性の高いコードを書くことができます。最後にJavaScriptにおいて、then()メソッドとcatch()メソッドを使用することで、Promiseを簡単にチェーンすることができます。then()メソッドは、追加されたPromiseが実行された時に行うべき操作を定義するために使用されます。catch()メソッドは、Promiseが拒否された場合に処理することができます。過去には、コールバック地獄という問題が存在しましたが、Promiseの導入によりこの問題が大幅に軽減されました。この手法に大きく依存することが必要です。ES2017以降では、async/awaitを使用することで、よりクリーンなコードを記述することができます。async/awaitは、Promiseを操作するための新しい構文であり、Promiseチェーン手法よりも優れています。当ブログでは、これについて詳しく解説していますので、是非参照し次のステップに移行してみてください。dev-k.hatenablog.com以上が、then()メソッドとcatch()メソッドを使用してJavaScriptでPromiseをチェーンする手順およびPromise概念の解説です。この記事が役に立った場合は、ブックマークや共有をお願い致します。17:56ご訪問いただきありがとうございます。私はdeve.Kと申します。現役のReact.jsプログラマーでありWebアプリ開発に携わっています。当ブログでは、ITやプログラミングの学習を目的としたブログを運営しています。専門分野はJS/TS/Node.js/React/Next.jsです。質問や相談、または学びたい分野のリクエストなどがありましたら、お気軽にお問い合わせください。このブログでは、ITやプログラミングに関する情報を分かりやすく、かつ実践的な内容でお届けしています。皆様にとって有益な情報を提供し、より良い学習体験を得ていただけるよう、精一杯の努力をしてまいります。今後ともどうぞよろしくお願いいたします。[deve.K].はてなブログをはじめよう!dev04Kさんは、はてなブログを使っています。ブログを報告する引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。