JavaScriptのPromiseとは、すぐには終わらない処理の結果を、あとで受け取るための仕組みです。
たとえば、サーバーからデータを取得する処理は、クリックした瞬間に結果が返ってくるとは限りません。通信には時間がかかりますし、失敗することもあります。
Promiseを使うと、そのような非同期処理に対して「成功したらこの処理」「失敗したらこの処理」「最後にこの処理」という形で、後続の処理を整理できます。

Promiseは「値そのもの」ではありません。まだ終わっていない処理の結果を、あとで受け取るための箱のようなものです。
この記事では、Promiseとは何か、then・catch・finallyの使い方、fetchやasync/awaitとの関係を初心者向けに順番に解説します。
まず結論:Promiseは非同期処理の結果をあとで受け取る仕組み
Promiseを最初に理解するときは、次のように考えると分かりやすいです。
非同期処理を始める
↓
Promiseが返る
↓
成功したら then
失敗したら catch
最後に finally
Promiseは、処理が終わる前に「将来の結果を表すオブジェクト」として返されます。MDNでも、Promiseは非同期処理の最終的な完了または失敗と、その結果の値を表すオブジェクトとして説明されています。
つまり、Promiseは「通信結果そのもの」ではなく、通信結果をあとで受け取るための窓口です。
Promiseが必要になる理由
JavaScriptでは、ブラウザ操作や通信処理など、すぐに終わらない処理がよく出てきます。代表例は、APIからデータを取得するfetchです。
もし通信が終わるまで画面全体が止まってしまうと、ユーザーは何も操作できません。そのためJavaScriptでは、時間がかかる処理を待っている間も、他の処理を進められるように非同期処理を使います。
ただし、非同期処理には問題があります。結果がいつ返るか分からないため、普通の変数代入の感覚で書くと、まだ結果がない状態を読んでしまいます。
そこでPromiseを使い、結果が返ってきたあとに実行する処理を登録します。
Promiseの3つの状態
Promiseには、処理の進み具合を表す状態があります。最初は細かい仕様名よりも、次の3つを押さえれば十分です。
| 状態 | 意味 | 初心者向けの見方 |
|---|---|---|
| pending | まだ結果が出ていない | 処理中 |
| fulfilled | 成功して結果が得られた | 成功した |
| rejected | 失敗して理由が返った | 失敗した |
Promiseは最初はpendingです。その後、成功すればfulfilled、失敗すればrejectedになります。
この図では、Promiseを「非同期処理の結果をあとで受け取る流れ」として見てください。thenは成功、catchは失敗、finallyは最後の後片付けに対応します。

then・catch・finallyの基本
Promiseでよく使うのは、then・catch・finallyの3つです。
| メソッド | 使う場面 | ざっくりした意味 |
|---|---|---|
then() | 成功したとき | 結果を受け取って次の処理をする |
catch() | 失敗したとき | エラーを受け取って処理する |
finally() | 成功・失敗に関係なく最後 | 後片付けをする |
一番シンプルな形は次の通りです。
fetch("https://example.com/api/users")
.then((response) => response.json())
.then((users) => {
console.log(users);
})
.catch((error) => {
console.error("取得に失敗しました", error);
})
.finally(() => {
console.log("処理が終わりました");
});
thenは成功した結果を次へ渡します。catchは途中で失敗したときに呼ばれます。finallyは、成功しても失敗しても最後に実行されます。
Promiseチェーンとは?
Promiseでは、thenをつなげて処理を順番に書けます。このつながりをPromiseチェーンと呼ぶことがあります。
次の例では、最初のthenでレスポンスをJSONに変換し、次のthenで変換後のデータを使っています。
fetch("/users.json")
.then((response) => response.json())
.then((users) => users.filter((user) => user.active))
.then((activeUsers) => {
console.log(activeUsers);
})
.catch((error) => {
console.error(error);
});
ポイントは、前のthenで返した値が、次のthenへ渡されることです。
配列のfilterやmapがあやふやな場合は、map・filter・reduceの違いも参考になります。
fetch APIとPromiseの関係
fetchは、HTTP通信を行うためのWeb APIです。そしてfetch()を呼び出すとPromiseが返ります。
そのため、fetchのコードではPromiseの理解がほぼ必須になります。
const promise = fetch("/api/users");
console.log(promise); // Promiseが入っている
この時点で得られるのは、ユーザー一覧そのものではありません。通信結果をあとで受け取るためのPromiseです。
fetchのGET・POSTの基本は、fetch APIとは?で詳しく解説しています。
async/awaitとの違い
async/awaitは、Promiseをより自然な順番で書くための構文です。Promiseと別物というより、Promiseを読みやすく扱うための書き方です。
Promiseチェーンで書くと次のようになります。
fetch("/api/users")
.then((response) => response.json())
.then((users) => console.log(users))
.catch((error) => console.error(error));
同じ処理をasync/awaitで書くと、次のようになります。
async function loadUsers() {
try {
const response = await fetch("/api/users");
const users = await response.json();
console.log(users);
} catch (error) {
console.error(error);
}
}
awaitはPromiseの完了を待ち、その結果を取り出します。async/awaitの基本は、async/awaitとは?の記事で解説しています。
初心者がつまずきやすいポイント
| つまずき | まずこう理解する |
|---|---|
| Promiseを値そのものだと思う | Promiseは将来の結果を表すオブジェクト |
| thenの中でreturnしない | 次のthenへ渡す値がなくなる |
| catchを書かない | 失敗時の動きが追いにくくなる |
| async/awaitならPromise不要と思う | async/awaitの裏側でもPromiseを扱っている |
特に多いのは、thenの中で値を返し忘れることです。次の処理に値を渡したい場合は、returnを意識しましょう。
Promiseをどんな場面で使うのか
Promiseは、次のような非同期処理でよく使われます。
ただし、最初からPromise.allやPromise.raceなどをすべて覚える必要はありません。まずはthen・catch・finallyと、async/awaitとの関係を押さえましょう。
関連して読みたい記事
まとめ
JavaScriptのPromiseは、非同期処理の結果をあとで受け取るための仕組みです。
Promiseを理解すると、fetchやasync/awaitのコードがかなり読みやすくなります。最初は「まだ終わっていない処理の結果を、あとで受け取る約束」と考えれば十分です。
