JavaScriptを学び始めると、しばらくして Promise という言葉が出てきます。最初は難しく見えますが、結論からいうと Promise とは「あとで結果が返ってくる処理」を扱いやすくするための仕組み です。
JavaScriptでは、API通信やタイマーのように、すぐには終わらない処理をよく扱います。そんなときに Promise の考え方を知っておくと、コードの流れを追いやすくなります。この記事では、まず「なぜ Promise が必要なのか」から順番に、初心者向けにわかりやすく解説します。
結論: Promise は「未来の結果」を扱うための仕組み
| 用語 | 意味 |
|---|---|
| 非同期処理 | すぐに終わらず、あとで結果が返ってくる処理 |
| Promise | その非同期処理の結果を表すオブジェクト |
then | 成功したときの処理を書く |
catch | 失敗したときの処理を書く |
finally | 成功・失敗に関係なく最後に実行する |
まずは「Promise をどう書くか」より、「Promise は何のためにあるのか」をつかむことが大切です。ここがわかると、そのあとの構文もかなり理解しやすくなります。
1. まずは非同期処理をイメージしましょう
JavaScriptには、書いた順にすぐ実行される処理だけでなく、少し待ってから終わる処理があります。たとえば setTimeout や API通信が代表例です。
console.log("開始");
setTimeout(() => {
console.log("3秒後に実行");
}, 3000);
console.log("終了");
このコードを実行すると、表示順は次のようになります。
開始終了3秒後に実行
つまり、JavaScriptは「待つ処理」をその場で止まって待つのではなく、いったん次へ進みます。これが非同期処理の基本イメージです。
2. Promise とは何か
Promise は、非同期処理が「まだ終わっていない」「成功した」「失敗した」といった状態を持ちながら、あとで結果を受け取れるようにする仕組みです。
| 状態 | 意味 |
|---|---|
pending | まだ処理中 |
fulfilled | 成功して結果が返った |
rejected | 失敗してエラーになった |
次のコードは、1秒後に成功メッセージを返す Promise の例です。
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("データの取得に成功しました");
}, 1000);
});
resolve は成功したときに使い、reject は失敗したときに使います。ここでは1秒後に成功したので resolve が呼ばれています。
3. Promise の結果は then と catch で受け取る
Promise の中に入っている結果は、すぐにそのまま取り出すのではなく、then や catch を使って受け取ります。
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("ユーザー情報を取得しました");
}, 1000);
});
promise
.then(result => {
console.log(result);
})
.catch(error => {
console.log(error);
});
成功したら then が実行され、失敗したら catch が実行されます。初心者のうちは、「成功なら then、失敗なら catch」 とまず覚えておけば十分です。
また、最後に必ず行いたい処理があるなら finally を使います。
promise
.then(result => {
console.log(result);
})
.catch(error => {
console.log(error);
})
.finally(() => {
console.log("処理が終わりました");
});
4. Promise が便利なのは、処理の流れを整理しやすいからです
Promise がない時代や、Promise を使わない書き方では、コールバック関数が深くネストして読みにくくなることがありました。
step1(function() {
step2(function() {
step3(function() {
console.log("完了");
});
});
});
このように入れ子が深くなると、どこからどこまでが1つの処理なのか見づらくなります。Promise を使うと、次のように上から順に読みやすく書けます。
step1()
.then(() => step2())
.then(() => step3())
.then(() => {
console.log("完了");
})
.catch(error => {
console.log(error);
});
この「流れが追いやすい」という点が、Promise が広く使われる大きな理由です。
5. Promise と async/await の関係
async/await は Promise をより読みやすく書くための構文です。つまり、Promise と別物ではなく、Promise を使いやすくした書き方だと考えるとわかりやすいです。
async function showMessage() {
const result = await Promise.resolve("完了しました");
console.log(result);
}
Promise 自体を理解しておくと、あとで async/await を学ぶときにもスムーズです。
6. よくあるつまずき
Promise オブジェクトそのものと、結果の値は別です
Promise を console.log すると、すぐに欲しい結果が見えるわけではありません。Promise は「結果そのもの」ではなく、「結果があとで入る箱」だからです。
catch を書かずに終わらせない
API通信などでは失敗することもあります。成功するケースだけでなく、失敗したときの処理も必ず意識しましょう。
then の中で次の処理へ値を渡すなら return が必要です
Promise をつなげて使うときに return を忘れると、次の then に値が渡らず混乱しやすくなります。チェーンを書くときは、この点を意識すると安定します。
関連して読みたい記事
まとめ
Promise は最初こそ難しく見えますが、考え方はシンプルです。まずは「すぐに終わらない処理の結果を、あとで受け取るための仕組み」と理解して、then と catch から少しずつ慣れていきましょう。
