Node.jsは、非同期プログラミングを強力にサポートするJavaScriptランタイムです。その中でも、setTimeout
関数は、特定の時間が経過した後に関数を実行するための基本的なツールです。
本記事では、setTimeout
の動作を深く理解するための実験を行い、さまざまな使い方や注意点を解説します。
1. setTimeoutの基本
setTimeout
は、指定した遅延時間(ミリ秒)後に関数を実行するためのメソッドです。基本的な構文は以下の通りです。
const timeoutID = setTimeout(callback, delay, [arg1], [arg2], ...);
callback
: 実行したい関数。delay
: 遅延時間(ミリ秒)。arg1
,arg2
, …: コールバック関数に渡す引数(オプション)。
1.1 簡単な例
以下のコードは、2秒後にメッセージをコンソールに表示するシンプルな例です。
setTimeout(() => {
console.log('Hello, Node.js!');
}, 2000);
このコードを実行すると、2秒後に「Hello, Node.js!」と表示されます。
2. setTimeoutの戻り値とキャンセル
setTimeout
は、タイマーIDを返します。このIDを使用して、clearTimeout
関数でタイマーをキャンセルすることができます。
2.1 タイマーのキャンセル
以下の例では、タイマーを設定し、その後すぐにキャンセルします。
const timeoutID = setTimeout(() => {
console.log('This will not run');
}, 3000);
clearTimeout(timeoutID);
このコードを実行すると、何も表示されません。タイマーがキャンセルされたためです。
3. setTimeoutの非同期性
setTimeout
は非同期で動作します。これは、指定した遅延時間が経過した後にコールバック関数が実行されることを意味します。以下の例を見てみましょう。
console.log('Start');
setTimeout(() => {
console.log('Inside setTimeout');
}, 1000);
console.log('End');
このコードを実行すると、出力は次のようになります。
Start
End
Inside setTimeout
setTimeout
は非同期であるため、最初に「Start」と「End」が表示され、その後1秒後に「Inside setTimeout」が表示されます。
4. setTimeoutの再帰的使用
setTimeout
を再帰的に使用することで、特定の条件が満たされるまで関数を繰り返し実行することができます。以下の例では、カウントダウンを行います。
function countdown(seconds) {
if (seconds < 0) {
console.log('Countdown finished!');
return;
}
console.log(seconds);
setTimeout(() => {
countdown(seconds - 1);
}, 1000);
}
countdown(5);
このコードを実行すると、5から0までのカウントダウンが1秒ごとに表示され、最後に「Countdown finished!」と表示されます。
5. setTimeoutでの引数の渡し方
setTimeout
では、コールバック関数に引数を渡すことができます。以下の例では、名前を引数として渡し、挨拶を表示します。
function greet(name) {
console.log(`Hello, ${name}!`);
}
setTimeout(greet, 2000, 'Alice');
このコードを実行すると、2秒後に「Hello, Alice!」と表示されます。
6. thisの扱い
setTimeout
内でのthis
の扱いには注意が必要です。通常、this
はグローバルオブジェクトを指しますが、オブジェクトのメソッドとして呼び出す場合、this
はそのオブジェクトを指すようにする必要があります。
6.1 bindを使用する
以下の例では、bind
を使用してthis
を明示的に設定します。
const dog = {
sound: 'woof',
bark() {
console.log(`The dog says: ${this.sound}`);
}
};
setTimeout(dog.bark.bind(dog), 1000);
このコードを実行すると、1秒後に「The dog says: woof」と表示されます。
7. arrow functionを使用する
ES6のアロー関数を使用すると、this
の扱いが簡単になります。アロー関数は、外側のスコープからthis
を継承します。
const cat = {
sound: 'meow',
meow: function() {
setTimeout(() => {
console.log(`The cat says: ${this.sound}`);
}, 1000);
}
};
cat.meow();
このコードを実行すると、1秒後に「The cat says: meow」と表示されます。
8. setTimeoutの精度
setTimeout
は、指定した遅延時間を保証するものではありません。特に、他の処理が実行中の場合、遅延時間が延びることがあります。以下の例を見てみましょう。
console.log('Start');
setTimeout(() => {
console.log('Timeout after 0 ms');
}, 0);
for (let i = 0; i < 1e9; i++) {} // CPU負荷をかける
console.log('End');
このコードを実行すると、出力は次のようになります。
Start
End
Timeout after 0 ms
setTimeout
は、現在のスクリプトが終了した後に実行されるため、CPU負荷のかかる処理があると、遅延が発生します。
9. setTimeoutとsetIntervalの違い
setTimeout
は一度だけ関数を実行しますが、setInterval
は指定した間隔で関数を繰り返し実行します。以下の例では、setInterval
を使用して1秒ごとにメッセージを表示します。
const intervalID = setInterval(() => {
console.log('This message appears every second');
}, 1000);
// 5秒後に停止
setTimeout(() => {
clearInterval(intervalID);
console.log('Interval cleared');
}, 5000);
このコードを実行すると、1秒ごとにメッセージが表示され、5秒後に「Interval cleared」と表示されます。
10. まとめ
setTimeout
は、Node.jsにおける非同期プログラミングの基本的なツールです。タイマーの設定、キャンセル、引数の渡し方、this
の扱い、精度など、さまざまな側面を理解することで、より効果的に活用できるようになります。特に、再帰的な使用やsetInterval
との違いを理解することで、より柔軟なプログラムを作成できるでしょう。
これらの実験を通じて、setTimeout
の動作を深く理解し、Node.jsでの非同期処理をマスターしましょう。