masakiのブログ Written by masaki shibayama

【中学生でもわかる】Promiseとは何かについてわかりやすく解説【エンジニアが噛み砕いて説明します】

Programming WebApp

こんにちは。masakiです。
今回は、Promiseとは何かについて、中学生にもわかるように噛み砕いて解説します。

Promiseとは何かについてわかりやすく解説

JavaScriptのPromiseって、すごくわかりにくいですよね。
ネット記事や書籍を読んでもわかりやすい説明がないし、そもそも文法が複雑で何がしたいのかがよくわからない。。

僕もJavaScript初心者の頃は、そう思ってました。
僕と同じようにPromiseについてのモヤモヤを抱えている人は多いと思ったので、今回はPromiseについてわかりやすく解説しようと思いました。

目次は以下のとおりです。

  • 同期処理と非同期処理
  • Promiseとは
  • resolveとreject
  • Promiseの3つの状態

それでは早速解説していきます。

同期処理と非同期処理

同期処理とは

同期処理とは、以下のように1つずつ前から順番に処理をしていくことです。

処理Aが終了してから処理Bに移り、処理Bが終了したら処理Cに移る、といった具合です。
これはめちゃくちゃシンプルなので、わかりやすいと思います。

普通のプログラムはこんな感じで順番に上から実行していくのですが、JavaScriptでは通信といって、バックエンドのデータをフロントエンド側で取得したりする処理が頻繁にあります。この通信には割と時間がかかるので、同期処理だけだと遅くて困ってしまうことがあるわけですね。

こちらも図にしてみると、以下のような感じです。

フロントエンドというのは、画面があったりとかユーザーが触れる側のことです。一方バックエンドというのは、データベースなどのデータを保持している部分など、ユーザーに見えない裏側といった感じです。

このフロントエンドとバックエンドでデータのやりとりをする際には、APIというものを介して通信をする必要があります。
APIとは何かについては以下の記事で解説していますが、ここではとりあえず、この通信の処理には時間がかかるということを抑えてもらえればと思います。
【中学生でもわかる】APIとは何かについてわかりやすく解説【エンジニアが噛み砕いて説明します】

非同期処理とは

非同期処理とは、読んで字のごとく、同期処理じゃない処理のことです。
イメージとしては以下のような感じ。

上の図について解説すると、まず普通に処理Aが行われます。そして、処理Bは非同期処理です。先ほどのバックエンドとの通信のような処理だと考えてください。
先ほど述べたとおり、一般的にこのような処理には時間がかかるので、バックグラウンドで処理Bを走らせ、処理C以降については処理Bと並行して走らせるようにします。
こうすれば、処理Bが終わるのを待たずに、他の処理を走らせることができます。

このように、バックグラウンドで走らせる処理Bのような処理のことを非同期処理と言います

Promiseとは

同期処理と非同期処理の違いがわかったところで、次はPromiseについて解説します。
Promiseとは、非同期処理の完了を約束するためのオブジェクトです。ちなみに英語のpromiseという単語は、「約束する」という意味です。

使い方としては以下のような感じ。


Promiseオブジェクト
.then(
  処理1
)
.then(
  処理2
)
.then(
  処理3
)
.catch(
  処理A
)

「Promiseオブジェクト」と書かれた部分では、実際には非同期処理を実行します。
具体的には、Promiseを返す関数をコールすることが多いです。

そして、その非同期処理が無事成功した場合には、thenの中の処理を実行します。

このthen()やcatch()の引数には、関数を取ります。
ちなみに、引数として渡した関数のことをコールバック関数と呼びます。

そして、then()の中のコールバック関数の戻り値としてPromiseを渡したとき、そのコールバック関数の中の処理が無事終われば、次のthen()の中の処理が実行されるといった感じになります。

こんな感じでどんどん連鎖的に処理を行っていくわけですね。

ちなみにcatch()の中の処理は、非同期処理が失敗した時に実行されます。
(この辺りについては後ほど解説します。)

resolveとreject

Promiseの文法的なことはここでは触れませんが、Promiseは2つの関数を持っています。
それが、resolve()とreject()です。

ちなみに、英単語の意味は以下のとおりです。

resolve: 解決する
reject: 断る

もっと噛み砕くと、JavaScriptの場合は、以下のような意味になります。

resolve: 非同期処理が成功した
reject: 非同期処理が失敗した

つまり、非同期処理が成功すればresolve()を実行し、失敗すればreject()を実行することで、成功や失敗の通知を内部的には行っているわけですね。

Promiseの3つの状態

最後は、Promiseの3つの状態についてです。
まず日本語だけで説明すると、Promiseには以下の3つの状態があります。

  • 成功した状態
  • 失敗した状態
  • まだ結果が出ていない状態

まあ考えてみれば当たり前ですよね。この辺は何も難しいことを言っていないはずです。

そして、この3つの状態のことをそれぞれ以下のように言います。

成功した状態: fulfilled
失敗した状態: rejected
まだ結果が出ていない状態: pending

このネーミングがまたちょっとわかりずらい。。
どうせなら、

成功した状態: resolved
失敗した状態: rejected
まだ結果が出ていない状態: waiting

とかにしておいてほしいですよね。

まあでもこの辺は仕方なしです。

状態の流れとしては、まず非同期処理が実行されるとPromiseの状態がpending(待機中)になります。
そして非同期処理が終わって内部でresolve()が実行されるとfulfilled(つまり成功した状態)、非同期処理が失敗してreject()が実行されるとrejected(つまり失敗した状態)になります。
fulfilledになると、then()の中の処理が実行され、rejectedになると、catch()内の処理が実行されるといった流れになります。

今回は以上です。
最後まで読んで頂き、ありがとうございました。
少しでもこの記事がためになりそうだと思った方は、twitterなどフォローして頂けると嬉しいです。それではまた次の記事でお会いしましょう!

参考

ちなみに、Promiseを理解する上では以下の書籍もわかりやすくてオススメです。