JavaScript | 第14章「プロミスの使用」

javascrpit JavaScript
スポンサーリンク

ここからは Promise の流れが実感できる実践ステップ を、実際に動かしながら学べる形で解説します。

ステップ1:Promiseの基本(「約束を返す」)

// 1. Promise を作る
const promise = new Promise((resolve, reject) => {
  console.log("Promiseの中: 非同期処理スタート");

  setTimeout(() => {
    // 成功とみなして結果を返す
    resolve("データ取得成功!");
    // reject("エラーが発生しました"); ← 失敗にしたいときはこちら
  }, 1000);
});

// 2. Promise を使う(消費する)
promise
  .then(result => {
    console.log("成功:", result);
  })
  .catch(error => {
    console.error("失敗:", error);
  })
  .finally(() => {
    console.log("処理が終わりました(成功・失敗どちらでも)");
  });
JavaScript

🧩 解説

  • new Promise(...) の中の関数は「executor」と呼ばれます。
  • resolve(...) を呼ぶと「成功状態」(fulfilled) に変わります。
  • reject(...) を呼ぶと「失敗状態」(rejected) になります。
  • .then() は成功時、.catch() は失敗時、.finally() はどちらでも最後に呼ばれます。

ステップ2:チェーン(順番に非同期処理をつなげる)

function getData() {
  return new Promise(resolve => {
    console.log("データ取得中...");
    setTimeout(() => resolve("🐶 犬データ"), 1000);
  });
}

function processData(data) {
  return new Promise(resolve => {
    console.log("データ処理中...");
    setTimeout(() => resolve(data + " → 🧠 処理完了"), 1000);
  });
}

getData()
  .then(result => {
    console.log("① 取得結果:", result);
    return processData(result); // 次の Promise を返す!
  })
  .then(finalResult => {
    console.log("② 最終結果:", finalResult);
  })
  .catch(error => {
    console.error("エラー:", error);
  })
  .finally(() => {
    console.log("③ 全処理完了");
  });
JavaScript

🧩 ポイント

  • .then() の中で「Promiseを返す」と、その完了を待って次の .then() に値が渡ります。
  • こうして「順番に実行する非同期処理」をスマートに書けるのが Promise の利点です。

ステップ3:エラー処理の流れを確認する

function failAfter(ms) {
  return new Promise((resolve, reject) => {
    setTimeout(() => reject(new Error(ms + "ms後にエラー")), ms);
  });
}

failAfter(1000)
  .then(() => {
    console.log("成功したらここ(今回は呼ばれません)");
  })
  .catch(err => {
    console.error("キャッチ:", err.message);
    // catch内でthrowすると、次のthenには「失敗」として伝わる
    throw new Error("catch内で再スロー");
  })
  .then(() => {
    console.log("これは実行されない(上で再スローしたため)");
  })
  .catch(err => {
    console.warn("再キャッチ:", err.message);
  })
  .finally(() => {
    console.log("最後に必ず実行される");
  });
JavaScript

🧩 ポイント

  • .catch() は、その前のどこかでエラーが出ても一括で処理できます。
  • .catch() の中で throw すると、次の then に渡る前にまた rejected になります。

ステップ4:複数の Promise をまとめて待つ(Promise.all)

const p1 = new Promise(resolve => setTimeout(() => resolve("🍎 りんご"), 1000));
const p2 = new Promise(resolve => setTimeout(() => resolve("🍌 バナナ"), 1500));
const p3 = new Promise(resolve => setTimeout(() => resolve("🍇 ぶどう"), 500));

Promise.all([p1, p2, p3])
  .then(results => {
    console.log("全部そろいました:", results);
  })
  .catch(error => {
    console.error("どれかが失敗:", error);
  });
JavaScript

🧩 ポイント

  • 全て成功すれば .then() に配列で結果が渡る。
  • 一つでも失敗したら .catch() に飛ぶ。
  • 並列に実行して「全部終わるのを待つ」時に便利。

ステップ5:async / await 版で書き換える(Promiseの表現を簡潔に)

Promise を理解したら、より読みやすく書ける async / await に進みましょう。

function fetchDogData() {
  return new Promise(resolve => {
    console.log("🐕 データ取得中...");
    setTimeout(() => resolve("🐶 犬データ取得完了"), 1000);
  });
}

async function main() {
  try {
    const data = await fetchDogData();
    console.log("結果:", data);
  } catch (error) {
    console.error("エラー:", error);
  } finally {
    console.log("処理完了!");
  }
}

main();
JavaScript

🧩 ポイント

  • async 関数の中では await が使えます。
  • await promise は「promise が解決するまで待つ」動きをします。
  • これは Promise の糖衣構文(中身は同じ)です。

練習課題

🌟 課題:
wait(ms) という関数を作って、「指定ミリ秒後に”完了”と出す Promise」を返してください。
それを使って、

  • 1秒待つ
  • 2秒待つ
  • 3秒待つ
    の順でログを出すように書いてみましょう。
// ↓ここを完成させてみましょう
function wait(ms) {
  return new Promise(/* ... */);
}

wait(1000)
  .then(() => console.log("1秒経過"))
  .then(() => wait(2000))
  .then(() => console.log("さらに2秒経過"))
  .then(() => wait(3000))
  .then(() => console.log("さらに3秒経過"))
  .finally(() => console.log("完了!"));
JavaScript
タイトルとURLをコピーしました