Node.js Timers モジュール
Node.js のtimersモジュールは、指定した時間後にコードを実行したり、指定した間隔でコードを繰り返し実行したりするための一連の関数を提供します。これらの機能は、遅延実行、定期タスク、タイムアウト制御を実装するのに非常に役立ちます。
とはいえtimersモジュールは Node.js のコアモジュールですが、そのメソッドは、例えばsetTimeout(), setInterval()とsetImmediate()グローバルに利用可能で、明示的なインポートは必要ありません。
主なタイマー関数
setTimeout()
setTimeout()関数は、指定したミリ秒後にコールバック関数を1回実行するために使用されます。
例
setTimeout(() => {
console.log('このメッセージは2秒後に表示されます');
}, 2000);
パラメータの説明
- コールバック関数:実行する関数
- 遅延時間:ミリ秒単位の時間(1000ミリ秒=1秒)
- オプションのパラメータ:コールバック関数に渡す追加のパラメータ
例
setTimeout((name, age) => {
console.log(`こんにちは、${name}、あなたは今年${age}歳`);
}, 1000, '山田', 25);
clearTimeout()
clearTimeout()以前に設定されたsetTimeout()タイマーをキャンセルするために使用されます。
例
console.log('このメッセージは表示されません');
}, 2000);
clearTimeout(timerId); // タイマーをキャンセル
setInterval()
setInterval()関数は、指定したミリ秒間隔でコールバック関数を繰り返し実行するために使用されます。
例
let counter = 0;
const intervalId = setInterval(() => {
counter++;
console.log(`これは第 ${counter}回目の実行`);
if (counter === 5) {
clearInterval(intervalId); // タイマーを停止
}
}, 1000);
clearInterval()
clearInterval()以前に設定されたsetInterval()繰り返しタイマーを停止するために使用されます。
例
console.log('このメッセージは繰り返し表示されます');
}, 1000);
// 5秒後にタイマーを停止
setTimeout(() => {
clearInterval(intervalId);
}, 5000);
setImmediate()
setImmediate()関数は、現在のイベントループの終了時にコールバック関数を実行するために使用されます。
例
setImmediate(() => {
console.log('コールバックをすぐに実行');
});
console.log(終了);
// 出力順序:
// 開始
// 終了
// コールバックをすぐに実行
clearImmediate()
clearImmediate()以前に設定されたsetImmediate()即時実行コールバックをキャンセルするために使用されます。
例
console.log('このメッセージは表示されません');
});
clearImmediate(immediateId);
タイマーの実行順序
Node.js のイベントループを理解することは、タイマーの実行順序を把握するために非常に重要です。以下は、いくつかのタイマーの実行順序です:
- 同期コード:最初に実行
- process.nextTick():現在のフェーズ終了直後に実行
- Promise コールバック:マイクロタスクキュー
- setImmediate():I/O コールバックの後に実行
- setTimeout() と setInterval():チェックフェーズで実行
例
setTimeout(() => console.log('setTimeout'), 0);
setImmediate(() => console.log('setImmediate'));
process.nextTick(() => console.log('nextTick'));
Promise.resolve().then(() => console.log('Promise'));
console.log(終了);
// 典型的な出力順序:
// 開始
// 終了
// nextTick
// Promise
// setTimeout
// setImmediate
高度な使い方と注意点
タイマーのキャンセル
すべてのタイマー関数は、Timeoutオブジェクトを返し、タイマーのキャンセルに使用できます。タイマーがすでに実行されていても、キャンセル関数を呼び出しても安全です。
例
clearTimeout(timeout); // タイマーが実行済みでも安全に呼び出せる
タイマーの精度
Node.js のタイマーは正確な実行時間を保証しません。これらは「少なくとも」待機する時間を示します。システム負荷やその他の要因により、実際の実行時間が影響を受ける可能性があります。
メモリリーク
クリアを忘れるsetInterval()タイマーはメモリリークの一般的な原因です。不要になったら必ずタイマーをクリアしてください。
例
setInterval(() => {
// 何らかの処理を実行
}, 1000);
// 正しい方法 - 適切なタイミングでタイマーをクリア
const interval = setInterval(() => {
// 何らかの処理を実行
if (someCondition) {
clearInterval(interval);
}
}, 1000);
再帰 setTimeout による setInterval の代替
固定間隔が必要だが、毎回の実行時間が一定でないタスクには、再帰setTimeout 比 setIntervalを使用する方が信頼性が高いです。
例
console.log('タスクを実行中...');
// タスクの実行時間が一定でないことをシミュレート
const delay = Math.random() * 1000;
setTimeout(doSomething, 1000 + delay);
}
setTimeout(doSomething, 1000);
実際の応用例
簡単なカウントダウンの実装
例
let current = seconds;
console.log(`カウントダウン開始:${current}秒`);
const timer = setInterval(() => {
current--;
if (current <= 0) {
clearInterval(timer);
console.log('カウントダウン終了!');
} else {
console.log(`残り時間:${current}秒`);
}
}, 1000);
}
countdown(5);
リクエストタイムアウト処理
例
return new Promise((resolve, reject) => {
const timeoutId = setTimeout(() => {
reject(new Error(`リクエストタイムアウト(${timeout}ms)`));
}, timeout);
fetch(url)
.then(response => {
clearTimeout(timeoutId);
resolve(response);
})
.catch(error => {
clearTimeout(timeoutId);
reject(error);
});
});
}
// 使用例
fetchWithTimeout('https://api.example.com/data')
.then(data => console.log(data))
.catch(error => console.error(error));
Node.js のtimersモジュールを習得することで、コードの実行タイミングを効果的に制御し、さまざまなタイマータスクや非同期制御フローを実装できます。
Node.js 組み込みモジュール