Promiseについて調べてみた
前回、chatGPTを使ってコールバック関数について調べてみました。
今回はasync/awaitについて調べてみます、、、と思ったのですが
その前にPromiseのきちんとした理解が必要そうです。
Promiseは非同期処理の際の結果に応じて処理を指定できるというものでした。
(質問)そもそもJavaScriptのPromiseってなに?
Promiseとは?
Promise は、非同期処理の結果を表すオブジェクト です。
非同期処理が 成功するか失敗するか を表し、それに応じた処理を行うことができます。
なるほど。オブジェクトなので、プロパティとメソッドを持つはずですね。
(質問)Promiseはオブジェクトなので、プロパティとメソッドを含みますか?
はい、Promise は オブジェクト なので、プロパティやメソッドを持ちます。
ただし、Promise の特性上、プロパティはほとんど使われず、
『主にメソッドを利用』します。
つまり最低限、メソッドの理解が必要ということになりそうです。
(202/3/15追記)
- Promiseには「内部ステータス」と「メソッド」が存在します。
- プロパティについてはほとんど使われずというより、定義上存在しないようです。
項目 | 内部ステータス(state) | メソッド |
---|---|---|
役割 | Promiseの進行状況を管理 | Promiseを操作・処理する |
種類 | pending / fulfilled / rejected | .then() / .catch() / .finally() など |
Promiseの内部ステータス
状態 | 説明 |
---|---|
pending(待機中) | 初期状態(非同期処理が終わっていない) |
fulfilled(成功) | 非同期処理が成功し、resolve() が呼ばれた |
rejected(失敗) | 非同期処理が失敗し、reject() が呼ばれた |
(質問)Promiseの引数のresolve, rejectとはなんですか?
Promiseの考え方
- 今すぐ結果がわからなくても、将来結果が得られることを約束する
- 成功(resolve) か 失敗(reject) のどちらかに必ず決着する
Promiseの実装方法
✅ 1. resolve() を使う(成功時)
const successPromise = new Promise((resolve) => {
setTimeout(() => resolve("成功!"), 1000);
});
successPromise.then(console.log); // 1秒後に "成功!"
✅ 2. reject() を使う(失敗時)
const failurePromise = new Promise((resolve, reject) => {
setTimeout(() => reject("エラー!"), 1000);
});
failurePromise.catch(console.error); // 1秒後に "エラー!"
Promiseのメソッド
✅ 1. then() と catch()
ここで.thenと.catchが出てきました。
初学者にとっては少しとっつき辛いやつです。。。
(質問)Promiseのthenとcatchはそれぞれ成功時と失敗時のメソッドを呼び出すものという理解であっていますか?
はい、その理解で合っています!
then は 成功時の処理(resolve) を、catch は 失敗時の処理(reject) を呼び出すためのメソッドです。
then と catch の基本
■then(onFulfilled, onRejected)
- 第1引数 (onFulfilled) → resolve() のときに実行される(成功時)
- 第2引数 (onRejected) → reject() のときに実行される(失敗時)
const p = new Promise((resolve, reject) => {
const success = true;
success ? resolve("成功!") : reject("失敗!");
});
p.then(
result => console.log("成功:", result), // 成功時の処理
error => console.error("失敗:", error) // 失敗時の処理(省略可能)
);
- 成功時 → console.log("成功: 成功!") が実行
- 失敗時 → console.error("失敗: 失敗!") が実行
■catch(onRejected)
catch() は then() の 第2引数 の代わりになる
エラーハンドリングを then() とは別に分けたいとき に使う
const p = new Promise((resolve, reject) => {
reject("エラーが発生しました!");
});
// 失敗時の処理をcatchで実行
p.then(result => console.log("成功:", result))
.catch(error => console.error("失敗:", error));
- catch() は チェーンの途中でエラーをキャッチできる のが強み!
✅ 2. finally()(成功・失敗どちらでも実行)
fetchData()
.then(console.log)
.catch(console.error)
.finally(() => console.log("処理終了!"));
✅ 3. Promise.all()(すべて成功したら実行)
const p1 = new Promise(resolve => setTimeout(() => resolve("p1 完了"), 1000));
const p2 = new Promise(resolve => setTimeout(() => resolve("p2 完了"), 2000));
Promise.all([p1, p2]).then(console.log); // ["p1 完了", "p2 完了"]
まとめ
プロパティなども理解しようとするともう少し複雑そうですが、
基本はこんなところでしょうか。
自身としてはこれまで非同期処理はfetch(async/await)ぐらいで、
Promiseを使う機会は少なかったのですがこれで少し理解できた気がします。
次回はasync/awaitについて調べてみたいと思います。
Discussion
それ Promise のメソッド じゃなくて 内部ステータスでは……?
詳しく言うと そのメソッドのインスタンスである Promise をそのまま返す も特性にあります。(新しいPromiseを作らない
Promise の定義には 公開されているプロパティの定義は無いです。(内部ステータスは見えないですし。
junerさん、コメントありがとうございます!
その通りですね。。。
メソッドはPromiseを活用する、の.then、.catch、.finallyなどの方でした。
プロパティについてもその通り、定義上存在しないというのが正しいようですね。
記事を訂正しておきました。
finally() で新しい Promise を作らない特性のメリット