一覧へ

同期 vs 非同期 — コールバック、Promise、async/await

JavaScript の非同期処理方法を、コールバックから Promise、async/await まで段階的に理解します。

中級
|
10
|
検証済み (2026-07)
進捗0/55 (0%)

同期と非同期 — コールバック、Promise、async/await

このトピックを終えると

同期と非同期の違いを説明でき、コールバック → Promise → async/await の発展の過程を理解します。


同期 — 一行ずつ順番に

同期 (Synchronous) は、コードが上から下に向かって一行ずつ実行される方法です。前の処理が終わらなければ、次の処理は開始されません。

javascript
console.log("1. 注文受付");
console.log("2. コーヒーの製造 (3分かかる)");
console.log("3. コーヒーの提供");
// 1 → 2 → 3 の順に実行

直感的ですが、問題点があります。コーヒーを製造している間は、何もできません。 ファイルの読み込みに5秒かかる場合、その間サーバーが停止し、データベースの照会に2秒かかる場合、その間他のユーザーの要求を処理できません。

非同期 — 待たずに次の処理へ

非同期 (Asynchronous) は、時間がかかる処理を開始し、完了を待たずに次のコードを先に実行します。処理が完了したら、後で結果を受け取ります。

javascript
const fs = require("fs");

console.log("1. ファイルの読み込み開始");

// 非同期 — ファイルの読み込みを開始し、すぐに次の処理へ
fs.readFile("data.txt", "utf8", (err, data) => {
  console.log("3. ファイルの読み込み完了:", data);
});

console.log("2. 次の処理を実行");

// 出力順序:
// 1. ファイルの読み込み開始
// 2. 次の処理を実行     ← 待たずに先に実行!
// 3. ファイルの読み込み完了: (ファイルの内容)

出力順序は 1 → 2 → 3 ではなく、1 → 2 → 3 です。数字だけ見ると同じに見えますが、2 番目が 3 番目よりも先に実行されます。ファイルが読み込まれるのを待たなかったためです。

コールバック — 非同期の最初の方法

上記のコードで (err, data) => { ... } の部分が コールバック (callback) 関数です。「処理が完了したら、この関数を呼び出してね」という意味です。

問題は、非同期処理が連続して必要な場合に発生します。

javascript
// コールバック地獄 (callback hell)
fs.readFile("a.txt", "utf8", (err, a) => {
  fs.readFile("b.txt", "utf8", (err, b) => {
    fs.readFile("c.txt", "utf8", (err, c) => {
      console.log(a + b + c);
      // インデントがどんどん深くなる...
    });
  });
});

このようにコールバックの中にコールバックがネストすると、コードが読みづらくなります。これを コールバック地獄 と呼びます。

Promise — コールバック地獄の解決

Promise は、「後で結果を返すという約束」です。.then() で連結すると、コールバック地獄なしに順番に処理できます。

javascript
const fs = require("fs").promises;

fs.readFile("a.txt", "utf8")
  .then(a => {
    console.log("a の読み込み完了");
    return fs.readFile("b.txt", "utf8");
  })
  .then(b => {
    console.log("b の読み込み完了");
    return fs.readFile("c.txt", "utf8");
  })
  .then(c => {
    console.log("c の読み込み完了");
  })
  .catch(err => {
    console.error("エラー発生:", err.message);
  });

インデントが深くなりません。.catch() でエラー処理も一箇所でまとめて行います。

async/await — 非同期を同期のように

async/await は、Promise をより読みやすく書くための構文です。非同期コードが同期コードのように上から下に向かって読みやすくなります。

javascript
const fs = require("fs").promises;

async function readAll() {
  try {
    const a = await fs.readFile("a.txt", "utf8");
    const b = await fs.readFile("b.txt", "utf8");
    const c = await fs.readFile("c.txt", "utf8");
    console.log(a + b + c);
  } catch (err) {
    console.error("エラー:", err.message);
  }
}

readAll();

await は「この処理が完了するまで待つ」という意味ですが、プログラム全体を停止させるのではなく、この関数だけを一時的に停止させ、他の処理は継続します。await を使用するには、関数に async を付ける必要があります。

現在の JavaScript では、ほとんどの場合 async/await を使用します。AI に非同期コードを要求する場合も、「async/await で記述してください」と言うと、最も読みやすいコードが生成されます。


→ 開発に適用: DevBench — AjaxとFetch

💬 質問・コメント

0件のコメント

ログインせずに投稿できます。ゲスト投稿は投稿者自身で編集・削除できません。

0/2000

読み込み中...