100秒で理解するPromise

2024/03/31に公開

そもそも非同期処理とは?

Promiseについて知るためには、まず非同期処理について知っておく必要があります。

以下の動画で、非同期処理について100秒で解説しているので、そもそも非同期処理をよく知らないなぁという人はぜひ確認してみてください!

https://youtu.be/wl_oOMFa1MM?si=1A8d0kqvYPsXQHS9

Promiseとは

では、本題です。
Promiseとは、ES2015で導入された、非同期処理の状態や結果を表現するオブジェクトのことです。

PromiseはES2015で導入された非同期処理の状態や結果を表現するビルトインオブジェクトです。 非同期処理はPromiseのインスタンスを返し、そのPromiseインスタンスには状態変化をした際に呼び出されるコールバック関数を登録できます。

jsprimer - 非同期処理:Promise/Async Function

例えば、出前アプリでピザを注文することをイメージしてみましょう。

ピザを注文すると、アプリの中で「準備中」か「配達済み」か「キャンセルされたか」の3つの状態を教えてくれます。

これと同じ様に、Promiseも3つの状態を持ちます。

具体的に言うと、まず最初は「pending」という保留中の状態になって、成功したら、「fulfilled」と呼ばれる状態になります。そして、もし失敗や例外が起こったら「rejected」と呼ばれる状態になります。

このように、Promiseの仕組みを使えば、注文したピザの状態を追跡するように、非同期処理の状態や結果を追跡できます。

Promiseの使い方

では、実際にPromiseを使ってみましょう!Promiseを作成するには、以下のように書きます。

new Promise(() => {})

これを実行したら、以下のようなPromiseオブジェクトが作られます。

▶ Promise {<pending>}

...よく見たら、「pending」という文字が書かれていますね。これは、先ほど述べたとおり、Promiseの初期状態、つまり「保留中」を示しています。では、この保留中の状態を「成功」や「失敗」に変えるには、どうすればよいでしょうか?

実は、Promiseのコールバック関数の中には、2つの引数を指定することができます。

1つ目の引数は「resolve」という関数で、これを呼ぶと作業が成功したということを示します。そして2つ目の引数は、「reject」という関数で、これを呼ぶと作業が失敗したことを示します。

では、早速この2つの関数を実行してみましょう!

new Promise((resolve, reject) => resolve("配達された!"))
// => ▶ Promise {<fulfilled>: '配達された!'}

new Promise((resolve, reject) => reject("キャンセルされた!"))
// => ▶ Promise {<rejected>: 'キャンセルされた!'}

それぞれ、結果として「fulfilled」と「rejected」という文字が表示されたのが分かると思います。

thenとcatchの使い方

では、最後に「then」と「catch」の使い方について解説して終わりたいと思います。

thenメソッドは、簡単に言うと、「成功したときはこうする」という指示をプログラムに伝える方法のことです。catchメソッドは、逆に「失敗したときはこうする」という指示を伝える方法のことです。

例えば、出前アプリで考えると、ピザが届いたら「美味しかった!」とレビューを送りたいですし、キャンセルされたら「返金してほしい!」とお願いしたいですよね。thenとcatchを使えば、こういった指示をプログラムに伝えることができます。

具体的には、以下のようなコードになります。

new Promise((resolve, reject) => resolve("配達された!")).then((text) =>
  console.log(text + "美味しかった!")
);

new Promise((resolve, reject) => reject("キャンセルされた!")).catch((text) =>
  console.log(text + "返金してほしい!")
);

これで、成功したら「配達された!美味しかった!」と表示されますし、失敗したら「キャンセルされた!返金してほしい!」と表示されるようになります。

ちなみに、以下のように、thenとcatchはまとめて書くこともできます。

promise
    .then((v) => console.log(v + "美味しかったのだ!"))
    .catch((v) => console.log(v + "返金してほしいのだ!"))

Discussion