2026年4月16日
JavaScript Promise と非同期処理とは?
JavaScriptには 非同期処理(ひどうきしょり) という概念があります。通常のプログラムは上から順番に実行されますが、非同期処理は「時間のかかる処理を待たずに次の処理を進める」仕組みです。
Promise(プロミス)は、非同期処理の結果を扱うためのオブジェクトです。「約束」という意味で、「後で結果を返すよ」という約束を表します。Web APIからデータを取得するfetch()や、タイマー処理など、JavaScriptの多くの場面で使われる重要な概念です。最初は難しく感じますが、パターンを覚えれば簡単に使いこなせます。
たとえば、レストランで料理を注文する場面を想像してください。注文(リクエスト)をしたら、料理ができるまで待つ間に他のこと(メニューを見る、会話する)ができます。料理が完成したら(Promise fulfilled)受け取り、もし品切れなら(Promise rejected)別の料理を選びます。これがPromiseの考え方です。
Promiseの3つの状態
- pending(保留中):処理が完了していない状態。Promiseが作られた直後はこの状態です。
- fulfilled(成功):処理が成功した状態。
resolve()が呼ばれるとこの状態になります。 - rejected(失敗):処理が失敗した状態。
reject()が呼ばれるか、エラーが発生するとこの状態になります。
一度fulfilledまたはrejectedになったPromiseは、状態が変わりません。これを「settled(確定)」と呼びます。
🔗 あわせてJavaScript問題ドリルもチェックしてみましょう。
Promiseを自分で作る
Promiseの仕組みを理解するために、自分でPromiseを作ってみましょう。
const myPromise = new Promise(function(resolve, reject) {
const success = true;
if (success) {
resolve('成功しました!');
} else {
reject('失敗しました…');
}
});
myPromise
.then(function(result) {
console.log(result); // '成功しました!'
})
.catch(function(error) {
console.log(error);
});
new Promise() の引数に渡す関数の中で、成功なら resolve()、失敗なら reject() を呼びます。
then・catchの使い方
// setTimeoutをPromiseで包む例
function wait(ms) {
return new Promise(function(resolve) {
setTimeout(resolve, ms);
});
}
wait(1000)
.then(function() {
console.log('1秒後に実行!');
return wait(1000);
})
.then(function() {
console.log('さらに1秒後!');
})
.catch(function(error) {
console.log('エラー:' + error);
});
📖 詳しくはイベント処理入門で解説しています。
async/await:より読みやすい書き方
async/await を使うと、Promiseを同期処理のように読みやすく書けます。
async function main() {
try {
await wait(1000);
console.log('1秒後に実行!');
await wait(1000);
console.log('さらに1秒後!');
} catch (error) {
console.log('エラー:' + error);
}
}
main();
async をつけた関数の中で await を使うと、Promiseの完了を待ってから次の処理に進みます。try/catchでエラーハンドリングもできるので、then/catchチェーンより読みやすいコードが書けます。現在のJavaScriptでは、async/awaitが主流の書き方です。
👉 ループ処理入門も参考にしてください。
実践例:fetch APIでデータを取得する
Promiseが最もよく使われるのは、Web APIからデータを取得する fetch() です。
// fetch()はPromiseを返す
async function getUser() {
try {
const response = await fetch('https://api.example.com/user/1');
if (!response.ok) {
throw new Error('データの取得に失敗しました');
}
const user = await response.json();
console.log(user.name);
} catch (error) {
console.error('エラー:', error.message);
}
}
getUser();
fetch() はPromiseを返すので、await で結果を待ちます。ネットワークエラーやサーバーエラーに備えて、必ず try/catch で囲みましょう。
📖 fetch API入門でさらに詳しく学べます。
よくある間違いとデバッグ方法
.catch() を忘れる
Promiseでエラーが発生したとき、.catch() がないとエラーが握りつぶされて原因がわからなくなります。必ず .catch() をつけましょう。
// NG: catchがない
fetch('/api/data').then(res => res.json());
// OK: catchでエラーを処理
fetch('/api/data')
.then(res => res.json())
.catch(err => console.error('エラー:', err));
async関数でawaitを忘れる
await をつけ忘れると、Promiseオブジェクトそのものが返されてしまい、期待した値が取得できません。
// NG: awaitがない → Promiseオブジェクトが入る
const data = fetch('/api/data');
// OK: awaitで結果を待つ
const response = await fetch('/api/data');
const data = await response.json();
📖 エラーハンドリング入門でtry/catchの使い方を学べます。
Promise.all:複数の非同期処理を並行実行
複数のPromiseを同時に実行して、すべて完了するのを待つには Promise.all() を使います。
async function loadAllData() {
const [users, posts] = await Promise.all([
fetch('/api/users').then(r => r.json()),
fetch('/api/posts').then(r => r.json())
]);
console.log(users, posts);
}
1つずつ順番に待つより、並行実行した方が速くなります。ただし、1つでも失敗するとすべて失敗扱いになるので注意しましょう。
まとめ
- ✅ 非同期処理:時間のかかる処理を待たずに次を進める仕組み
- ✅ Promise:非同期処理の結果を扱うオブジェクト
- ✅ then:成功時の処理、catch:失敗時の処理
- ✅ async/await:Promiseをより読みやすく書ける構文
- ✅ .catch() を必ずつけてエラーを処理する
Promiseはfetch APIなどで必須の知識です。Web APIからデータを取得する場面で毎回使うので、しっかり理解しておきましょう。レッスンでさらに実践的な使い方を学んでみてください。
🚀 JavaScriptをレッスンで学ぼう!
このサイトのJavaScriptコースでは、非同期処理を含む実践的なプログラムをブラウザだけで学べます。無料・登録不要です。
JavaScriptコースを見る →