イベントループ

Node.js のシングルスレッドで非同期 I/O を実現する実行モデル

Node.js非同期

イベントループとは

イベントループは、Node.js のシングルスレッドで非同期 I/O を実現する実行モデルである。コールスタック、タスクキュー、マイクロタスクキューを巡回し、非同期コールバックを順番に実行する。

動作の流れ

イベントループはコールスタックが空になるたびに、まずマイクロタスクキュー (Promise の .then など) をすべて処理し、次にタスクキュー (setTimeout、I/O コールバック) から 1 つ取り出して実行する。このサイクルを繰り返すことで、シングルスレッドでも非同期処理を効率的にさばく。

1. コールスタックが空か確認
2. マイクロタスクキュー (Promise) を全て実行
3. タスクキュー (setTimeout, I/O) から 1 つ実行
4. 1 に戻る

┌─────────────────────────┐
│      コールスタック        │ ← 同期コードを実行
└────────────┬────────────┘
             ↓
┌─────────────────────────┐
│   マイクロタスクキュー     │ ← Promise.then, queueMicrotask
└────────────┬────────────┘
             ↓
┌─────────────────────────┐
│     タスクキュー          │ ← setTimeout, setInterval, I/O
└─────────────────────────┘

実行順序

実行順序のコード例を示す。

console.log('1');                    // 同期
setTimeout(() => console.log('2'), 0); // タスクキュー
Promise.resolve().then(() => console.log('3')); // マイクロタスク
console.log('4');                    // 同期

// 出力: 1, 4, 3, 2
// 同期 → マイクロタスク → タスクキュー の順

Node.js のイベントループフェーズ

Node.js のイベントループフェーズを以下にまとめる。

フェーズ 処理内容
timers setTimeout, setInterval のコールバック
pending callbacks I/O コールバック
poll 新しい I/O イベントを取得
check setImmediate のコールバック
close callbacks socket.on('close') 等

ブロッキングの問題

ブロッキングの問題のコード例を示す。

// ❌ イベントループをブロック (他のリクエストが処理できない)
function heavyComputation() {
  for (let i = 0; i < 1e9; i++) { /* CPU 集約的な処理 */ }
}

// ✅ Worker Threads で別スレッドに逃がす
import { Worker } from 'worker_threads';
const worker = new Worker('./heavy.js');

シングルスレッド vs マルチスレッド

シングルスレッドとマルチスレッドの違いを以下にまとめる。

観点 Node.js (イベントループ) Java (スレッドプール)
I/O 処理 高速 (ノンブロッキング) スレッドごとにブロック
CPU 処理 苦手 (シングルスレッド) 得意 (マルチスレッド)
メモリ 少ない スレッドごとにスタック
複雑さ コールバック/Promise デッドロック、競合

詳しくは関連書籍を参照。

この記事は役に立ちましたか?

関連用語

関連する記事