Frontend Academy · レッスン

Promise:then・catch・finally・Promise.all

Promise を作成して連結し、catch ブロックでエラーを処理し、finally で後処理を実行し、Promise.all で複数の Promise を並列実行します。

レッスン 3/413 ステップ

「Promise:then・catch・finally・Promise.all」はCoddyKit上の無料Frontend Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはFrontend Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Frontend Academyコースには全4レッスンが含まれています。

Promise とは

Promise は、将来利用可能になる値を表します。Promise は次の 3 つの状態のいずれかを持つオブジェクトです。pending(待機中)、fulfilled(履行済み)、rejected(拒否済み)。いったん状態が確定すると、Promise の状態は変わりません。

Promise の作成

new Promise(executor) コンストラクターを使って Promise を作成します。executor 関数は resolve と reject のコールバックを受け取ります。成功時の値を指定して resolve を呼び出すか、エラーを指定して reject を呼び出します。

const delay = (ms) => new Promise((resolve) => {
  setTimeout(resolve, ms);
});

const fetchData = (url) => new Promise((resolve, reject) => {
  fetch(url)
    .then(res => res.json())
    .then(resolve)
    .catch(reject);
});

.then() — 成功時の処理

promise.then(onFulfilled) は、Promise が fulfilled になったときに実行されるコールバックを登録します。コールバックは解決された値を受け取ります。.then() は新しい Promise を返すため、処理を連鎖させることができます。

fetch('/api/users')
  .then(response => response.json())
  .then(users => {
    console.log('Users:', users);
    return users.length;
  })
  .then(count => console.log('Count:', count));

.catch() — エラー処理

promise.catch(onRejected) は rejected になった Promise を処理します。連鎖の最後に配置すると、それより前のどのステップで発生したエラーも捕捉できます。

fetch('/api/data')
  .then(res => {
    if (!res.ok) throw new Error(`HTTP ${res.status}`);
    return res.json();
  })
  .then(data => processData(data))
  .catch(err => {
    console.error('Failed:', err.message);
    showErrorToUser();
  });

.finally() — 常に実行

promise.finally(onFinally) は、Promise が fulfilled になった場合でも rejected になった場合でも実行されます。読み込みスピナーを非表示にする、ロックを解放する、分析データを記録するといった後片付けに最適です。

showSpinner();
fetch('/api/data')
  .then(res => res.json())
  .then(render)
  .catch(handleError)
  .finally(() => hideSpinner()); // always runs

Promise の連鎖 — 値を返す

.then() から値を返すと、その値が次の .then() で解決された値になります。新しい Promise を返すと、非同期処理を順番に連鎖させることができます。

getUser(id)
  .then(user => getOrders(user.id))  // return Promise
  .then(orders => orders[0])          // return value
  .then(order => console.log(order)); // receive order

Promise.all() — 並列実行

Promise.all([p1, p2, p3]) はすべての Promise が解決されるまで待機し、同じ順序の結果を配列として返します。いずれかの Promise が rejected になると、全体が直ちに rejected になります。

const [user, posts, comments] = await Promise.all([
  fetch('/api/user/1').then(r => r.json()),
  fetch('/api/posts').then(r => r.json()),
  fetch('/api/comments').then(r => r.json()),
]);
// All three run in parallel — much faster than sequential

Promise.allSettled() — 早期失敗を避ける

Promise.allSettled() はすべての Promise が確定する(resolve または reject)まで待機し、{status, value} または {status, reason} を持つ結果オブジェクトの配列を返します。1 つの失敗によってすべての結果が失われるのを避けたい場合に便利です。

const results = await Promise.allSettled([p1, p2, p3]);
results.forEach(result => {
  if (result.status === 'fulfilled') use(result.value);
  else logError(result.reason);
});

Promise.race() と Promise.any()

Promise.race() は、最初に確定した Promise の結果で resolve または reject になります。Promise.any() は、最初に fulfilled になった Promise の結果で resolve になります(rejected は無視し、すべてが rejected の場合にのみ reject になります)。タイムアウトや冗長化に便利です。

// Timeout pattern:
const withTimeout = (promise, ms) => Promise.race([
  promise,
  new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout')), ms))
]);

確定済みの Promise を作成する

Promise.resolve(value) は、value ですでに fulfilled になっている Promise を作成します。Promise.reject(error) は、すでに rejected になっている Promise を作成します。テストやアダプター関数に便利です。

const p = Promise.resolve(42);
p.then(v => console.log(v)); // 42

未処理の拒否イベント

Promise が .catch() なしで reject されると、未処理の拒否になります。最新のブラウザーや Node.js は警告を出力します。必ず .catch() を登録するか、async/await と try/catch を使用してください。

window.addEventListener('unhandledrejection', event => {
  console.error('Unhandled rejection:', event.reason);
  event.preventDefault();
});

確認問題

複数の Promise を並列実行し、すべての結果を配列として返す静的メソッドはどれですか?

まとめ:Promise

.then() は成功時、.catch() はエラー時、.finally() は後片付けに使用します。連鎖によって値が受け渡されます。Promise.all() は処理を並列化します。Promise.allSettled() は一部の失敗を許容します。Promise.race() は最も早い結果を取得する場合に使用します。必ず reject を処理してください。最新のコードでは、Promise の構文糖衣である async/await を使用します。

無料で開始

AI チューターと学ぶ HTML — 無料

ブラウザでリアルコードを書いて実行し、24/7 の AI チューターから瞬時にサポートを受け、ウェブまたはアプリで続きから学習できます。

コース
41
レッスン
163

よくある質問

「Promise:then・catch・finally・Promise.all」レッスンは無料ですか?

はい。「Promise:then・catch・finally・Promise.all」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Frontend Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Frontend Academyコースには全4レッスンが含まれています。

「Promise:then・catch・finally・Promise.all」で何を学びますか?

Promise を作成して連結し、catch ブロックでエラーを処理し、finally で後処理を実行し、Promise.all で複数の Promise を並列実行します。 ブラウザで直接実行するハンズオンコードでFrontend Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Frontend Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのFrontend Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。

「Promise:then・catch・finally・Promise.all」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このFrontend Academyレッスンでコードを書いて実行できますか?

はい。すべてのFrontend Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. イベントループ:コールスタック・キュー・マイクロタスク
  2. コールバックとコールバック地獄
  3. Promise:then・catch・finally・Promise.all
  4. async/await とエラーハンドリング
← Frontend Academyに戻る