2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

JavaScriptの非同期処理をレストランで例えてみる

Posted at

JavaScriptの非同期処理をレストランに例えて理解しよう!

JavaScriptの非同期処理とイベントループは初心者にとって理解が難しい概念です。この記事では、レストランという身近な例えを使って、JavaScriptの実行モデルをわかりやすく解説します。

ChatGPT Image 2025年5月14日 08_45_21.png

🍽️ JavaScriptの実行モデルをレストランにたとえる

用語 レストランの役割 JavaScriptの役割
メインスレッド 席に座っているお客様(現在対応中) 今実行中のタスク(関数や処理が走っている状態)
タスクキュー 順番待ちのお客様(料理が来るのを待っている) 非同期処理の結果待ち(setTimeoutやイベント)
イベントループ シェフ(空いた席がないかを確認し料理を運ぶ) メインスレッドが空いたかを確認し、次の処理を実行

📝 具体例:レストランでの流れ

💡 シチュエーション

  1. お客様(メインスレッド)が席に座って食事中
    • 他の客(非同期処理)は順番待ち(タスクキュー)
  2. 順番待ちのお客様(非同期処理)が「デザート(setTimeout)」を注文
    • シェフ(イベントループ)は「3分後に出します」と仮予約
    • デザートができても、テーブルが空いてないと出せない
  3. 食事中のお客様(メインスレッド)が長々と食事を続ける(ブロッキング処理)
    • デザートが出来上がっても、席が空くまで運べない
  4. やっと席が空いた(メインスレッドが解放された)
    • シェフ(イベントループ)が**デザート(非同期タスク)**を運ぶ

📝 JavaScriptでの動きに置き換える

コード

console.log("Start");

setTimeout(() => {
  console.log("Dessert served");
}, 3000); // 3秒後に実行予約

const startTime = new Date();
while (new Date() - startTime < 5000); // 5秒間の食事(ブロッキング)

console.log("Main course done");

実行結果

Start
Main course done
Dessert served

🍰 解釈

  1. Startを出力
    • 最初のお客様が席に座り、メインディッシュを食べ始めた
  2. setTimeoutで「3秒後にデザートを出す」とシェフが予約
    • デザート注文がタスクキューに入るが、まだ運ばれない
  3. 5秒間のブロッキング(食事中)
    • お客様がメインディッシュを食べ続けているため、シェフがデザートを出すタイミングを逃す
  4. 食事が終わり席が空いた(メインスレッドが解放)
    • シェフが順番待ちのデザートをすぐに運ぶ

🔍 イベントループの流れを図解

  ┌─────────────────────┐
  │     メインスレッド     │
  │  (現在席に座っている人) │
  └──────────┬──────────┘
             │
             │ 完了
             ▼
  ┌─────────────────────┐      ┌─────────────────────┐
  │    イベントループ     │ 次へ │     タスクキュー       │
  │  (席が空いたか確認)   │◄─────┤ (デザート提供待ち)     │
  └──────────┬──────────┘      └─────────────────────┘
             │
             │ 空席確認
             ▼
 ┌─────────────────────────┐
 │メインスレッドが空いている?│
 └────────────┬────────────┘
              │
    ┌─────────┴─────────┐
    │                   │
    ▼                   ▼
【はい】席が空いた      【いいえ】まだ食事中
    │                   │
  ▼                     │
次のタスクを実行           │
   │                    │
   └────────────────────┘

🍽️ よりわかりやすくするポイント

「テーブルが空かないと料理が出せない」

  • メインスレッドが空かないと、非同期処理が実行されない
  • デザートが出来ても、テーブルが塞がっていれば運べない

「料理を運ぶのはシェフ」

  • シェフ(イベントループ)は、メインスレッドが空いたかを確認して、空いたら次の料理を運ぶ
  • シェフ自体が料理を作るわけではなく、タイミング管理が仕事

「非同期処理は予約しているだけ」

  • デザートを頼んだからといって、すぐに出てくるわけではない
  • 予約が通っても、実際に提供されるのは席が空いてから

💡 このたとえで覚えるポイント

  1. メインスレッド(席に座っているお客様)が食事をしている間は、他の料理が出せない
  2. タスクキュー(順番待ちの料理)は、メインスレッドが空いたとき順番に提供される
  3. イベントループ(シェフ)は、メインスレッドが空いたかを常に監視し、空いた瞬間に次のタスクを持ってくる
  4. 非同期処理(デザートの予約)は、**後で実行するという「約束」**であり、予約が成立してもすぐには実行されない

🚀 補足:もしメインスレッドが常に埋まっていたら?

  • **ずっと席に座り続ける客(whileループでブロッキング)**がいると、予約していた料理が出せない
  • 結果として、デザートが溜まってしまい、提供が遅れる
  • 席が空いた瞬間にまとめて運ばれるが、注文タイミングが遅くなってしまう。

✅ まとめ

  • メインスレッド=現在の仕事中のお客様:終わらない限り他の処理はできない
  • タスクキュー=次に実行したい非同期処理の待機列:メインスレッドが空くのを待っている
  • イベントループ=シェフ:メインスレッドが空いたときに次のタスクを実行
  • 非同期処理=予約:実行タイミングが来ても、席が空いていないと実行できない

👨‍💻 実際に確認してみよう

以下のコードを実行して、実際の動きを確認してみましょう:

console.log("🍽️ お客様が入店しました");

// メインコースの注文
console.log("🍖 メインコースを注文しました");

// デザートを3秒後に予約
setTimeout(() => {
  console.log("🍰 デザートが提供されました");
}, 3000);

// 5秒かかるメインコース(ブロッキング処理)
console.log("🕒 メインコースを食べています...");
const startTime = new Date();
while (new Date() - startTime < 5000);

console.log("✅ メインコースを食べ終わりました");

// 結果:
// 🍽️ お客様が入店しました
// 🍖 メインコースを注文しました
// 🕒 メインコースを食べています...
// ✅ メインコースを食べ終わりました
// 🍰 デザートが提供されました

この例では、3秒後にデザートを出す予約をしましたが、メインコースに5秒かかったため、デザートはメインコースが終わった後に提供されました。これがJavaScriptの非同期処理の基本的な流れです!

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?