まとめ「Promise」とは?まず最初に「Promise」を理解するための基本的な知識から学習していきましょう。理解と、「コールバック」について学びます。理解が必要ですのでおさらいしておきます。JavaScriptはシングルスレッドで実行されるので、普通にプログラミングすると同期処理になります。同期処理(前の処理が終わるまでストップ)例えば、サーバーからデータを取得するような場合は時間が掛かるので、通信が完了するまで待たなくてはいけません。このような欠点を解消するために、JavaScriptでは「非同期処理」という仕組みが用意されているわけです。非同期処理は、時間の掛かりそうな処理を実行したあとに結果を待たずにすぐ次の処理を実行できます。基本について、まずは慣れておくようにしましょう!「コールバック」を使ったプログラム非同期処理の結果を元にして、何らかの処理を実行する方法も合わせて見てみましょう!例えば、日付データを取得したあとにそのデータを使って西暦を抽出する場合を考えてみます。関数B(日付データから西暦を抽出する)(この内容なら処理を分ける必要はないのですが、概念を解説するために意図的に分けています)それぞれの処理を普通に記述すると、以下のようになります。data.getFullYear();}「getDate()」が日付を取得する処理で、「getYear()」がその日付から西暦を抽出する処理になります。ここで重要なのは、日付データを取得しないと「getYear()」が実行できないという点です。そこで、日付データを元にして処理をするためにgetDate()へ「コールバック」を実装しましょう。Date);}このように、「getDate()」の引数にコールバックを設定すれば関数を指定できるようになります。すると、次のように実行できるのです。getYear(data);});このように記述することで、日付データを取得したあとに「getYear()」を実行できるわけです。同じ仕組みで、サーバーからデータを取得したあとにそのデータを使って処理を行うようなことも実現できます。「コールバック地獄」について「非同期処理」と「コールバック処理」は組み合わせてよく使われるのですが、複雑化しやすいという欠点があります。先ほどの例は、日付を取得して西暦を抽出するだけだったので問題ありません。ところが、さらに別の処理が追加されていくと階層構造がどんどん複雑になっていくわけです。});});こうなるとコードの見通しが悪くなるばかりか、大きなバグを引き起こしやすくなります。このような状態を「コールバック地獄」と呼びます。そこで、この問題を解消してくれるのが本記事のテーマである「Promise」という処理なのです!「Promise」の使い方この章では、実際に「Promise」を使ったプログラミング手法について見ていきましょう!基本的な書き方から「then」によるコールバック処理について学んでいきます。基本的な構文と書き方についてそれでは、基本となるPromiseの書き方から学んでいきます。最初に知っておくべきことはPromiseオブジェクトの作り方です!このPromiseオブジェクトを作成することで、簡潔に非同期処理を実現することができるわけです。一般的にはnewを使ってPromiseのインスタンスを作成し、その「返り値」としてPromiseオブジェクトを取得します。)Promise()の引数には関数を設定し、その中で行いたい処理を記述するのが一般的です。日付を取得するPromise処理は次のようになります。Date」で日付を取得しています。関数の引数「resolve」に取得したい値を設定することで、非同期処理の結果を格納することができるようになります。(※実際にはエラー処理も必要ですが、これについては後述します)最終的に変数「result」にはPromiseオブジェクトが可能されることになります。「then」を使ったコールバック処理を行う方法Promiseは「then()」を使うことでコールバックのような処理を実現できます。先ほど作成したPromiseは最終的に変数「result」にPromiseオブジェクトが格納されました。);実行結果2019このように「then」の処理内で返されたPromise(data)を使って「getFullYear()」を実行すれば西暦を取得できます。ちなみに、ES2015(ES6)の書き方であればさらにスマートな記述が可能です。);チェーンを使ったPromise処理この章では、Promise処理をチェーンで繋げて処理する方法について見ていきましょう!主に、then()をチェーンで処理する方法やall()で並列処理する方法について学んでいきます。Promise処理を連結する方法Promise処理のチェーンによる連結処理について、まず最初に冒頭でも解説したコールバック地獄についておさらいしておきましょう!例えば以下のような状態です。});階層構造がどんどん複雑化してしまってコードの見通しが悪くなり、デバッグも困難な状態です。})1つ目のチェーンのあとに続けてthen()の処理を実行し、そのあとにまた別のthen()を繋げるという感じですね。これにより階層構造が複雑化しにくいため、コードの見通しもよくなるわけです。注意点として「then」を繋げて処理をする場合は、処理の最後に「return」で別のPromiseオブジェクトを返すようにしましょう。「all」で複数のPromise処理を連結する方法これまでは、Promiseを使って非同期処理を同期的に連結して実行していました。Promiseを使うと複数の非同期処理を同時に実行してすべて終了したあとに別の処理を行うことも可能です。「setTimeout()」を使って擬似的に時間の掛かる処理を作ってみます。})}これは3秒後に実行されるPromise処理で、resolveに指定した単純な文字列が返されます。同じ処理内容を「1秒後」「0.5秒後」と時間だけ違う関数を3つ作りましょう。これらのPromise処理を同時に実行して、すべて完了したら次の処理を行うには「all()」を使います。something3()])このように「all()」の中に配列として同時に実行したい関数を指定するだけです。すべて完了したあとに次の処理を記述したければ「then」で繋げていけば良いので簡単です。"3つ目の処理"]すべての処理が終了しました!このように、「then」の中に記述した処理はすべての関数が実行されてから発動します。注目して欲しいのは「then」で受け取る引数「data」の値です。実行結果を見ると、配列としてそれぞれのPromiseで指定したresolve()の値が格納されています。そのため、それぞれの実行結果をまとめて管理できるというメリットもあるので覚えておきましょう!「Promise」でAjax通信この章では、Promise処理においてよく使われるAjax通信の作り方について見ていきいましょう!一般的な「XMLHttpRequest」による手法を詳しく学んでいきいます。「XMLHttpRequest」による通信方法の書き方まずは、おさらいとして「XMLHttpRequest()」を使ったAjax通信の方法を見ていきいましょう!処理の流れとしては、次のとおりです。}}ポイントは、「onreadystatechange」を使ってサーバーとの通信が正常に完了しているかを確認することです。基本的なAjax通信の方法を把握したところで、Promiseを実装していきましょう!基本的な考え方は、これまでのPromise処理と同じなので難しくはありません。}基本となるプログラムは先ほどとほとんど同じです。違うのは「XMLHttpRequest()」を使ったコードを丸ごとPromise処理で囲んでいる点です。GitHubからJSONデータを取得できるので、その中からリポジトリ総数だけを取得します。あとは、それを「resolve()」に指定すればPromise処理の完成ですね。385083このように「then」から受けとる「response」には、リポジトリ総数が格納されています。エラーハンドリングについてこの章では、Promiseのエラーハンドリングについて見ていきましょう。基本となる条件分岐について学んでいきます。Promiseでエラー処理を条件分岐する方法これまでのPromise処理では、すべて正常に動作した場合の記述だけをしてきました。場合によってはPromiseが正しく動作しないケースも少なくありません。そのため、基本的にはエラーが発生した場合の処理も一緒に記述するべきでしょう。前章のAjax通信の場合であれば次のようにエラー処理を記述します。}}})これまで、Promiseが正常に実行された場合は「resolve」を使っていましたが、エラー処理の場合は「reject」を使います。reject」はペアで一緒に使われるので覚えておきましょう!実行するには次のように記述します。);})これまでは「then」の第1引数だけを使っていましたが、第2引数に「reject()」のPromiseが返るようになっています。そのため、エラー処理を記述する場合は上記サンプルのように第2引数を使いましょう!「Promise」の使い方まとめ最後に、Promiseの基本的な使い方をまとめておきます!Promiseを使うためには、まず最初にPromiseオブジェクトを作成する必要があります。一般的にはPromiseのインスタンスを作成する際に返り値としてPromiseオブジェクトを取得することができます。)Promise()の引数には非同期で処理を行いたい関数を記述します。Promiseで日付を取得したい場合は次のようになります。);Promiseの引数に設定した関数の「resolve」に値を格納することで、非同期で処理した結果をthen()を使って取得することができます。then()はチェーンで連結することも可能です。})これにより複雑な階層構造を構築する必要がなく、コードの見通しが良くなるわけです。all()を利用することで複数のPromise処理を並列に実行することが可能です。console.log('すべての処理が終了しました!');})この場合、thenで得られる値はすべてのPromise処理が終了した結果になります。まとめ今回は、非同期処理を完結に記述できる「Promise」について学習しました。・Ajax通信に関しても同じようにPromiseが利用できる・エラーハンドリングには「reject()」を使って処理を行う上記内容を踏まえて、ぜひ自分でもプログラミングに取り入れて活用できるように頑張りましょう!TweetPocket無料でSEからWebエンジニアへ転職しませんか?侍エンジニア塾では、完全未経験の方から現在SEだけどプログラミングはやっていないという経験者まで、幅広い方々の人生を好転させるプログラミング指導を行ってきました。SEの方とお話していくなかで、システムエンジニアという職業だけどコードが書けない事務作業が多くスキルがないため将来が不安スクールに通うと完全未経験者と同じスタートになるからレベルが合わないという、すでに知識があるSEならではのお悩みがあることに気づきました。弊社では、マンツーマンでレッスンを行いますので、現在お持ちの知識レベルからカリキュラムを作成いたします。こちらの転職コースは無料で受講を始められて転職成功でそのまま卒業できるというとてもお得なコースとなっています。知識のあるSEといっても転職は年齢が若いほど受かりやすいため、まずは無料体験レッスンで今の現状や理想の働き方について一緒に考えていきましょう。無料体験レッスンを予約する書いた人マサトフリーランスのIT系ライターを8年従事。侍ブログ編集部としては、これまで270記事以上の記事を執筆。Linuxを3年学習。個人プロダクトのWebメディア・アプリ作成経験あり。