JavaScriptでは、setTimeout(callback, delay)
は「callback
ミリ秒後にdelay
を呼び出す」ことを意味します。しかし、delay
が0
である場合はどうでしょうか? callback
をすぐに呼び出す必要がありますか?
次のコードを実行すると表示されるものが原因で混乱しています。
setTimeout(function() {
console.log('AAA');
}, 0); // Call this in 0 milliseconds
for (i = 0; i < 1000; i++) {
console.log('BBB');
}
for (i = 0; i < 1000; i++) {
console.log('CCC');
}
for (i = 0; i < 1000; i++) {
console.log('DDD');
}
for (i = 0; i < 1000; i++) {
console.log('EEE');
}
これにより、以下がコンソールに記録されます。
AAA
がそれよりずっと早く記録されるのを期待していました。すぐに呼び出されるべき関数の前に、console.log
への4000の呼び出しを実行する時間がありました。
遅延が0ミリ秒に設定されている場合、誰かがsetTimeout
が何をしているのか説明できますか?
いくつかの有用な事実は、何が起こっているのかを明確にするのに役立ちます。
setTimeout
は、指定された遅延が経過した後、このキューの最後に(提供されたコールバックを使用して)メッセージを追加します。(注:これは、setTimeout
呼び出しの遅延が確実なものではないことを意味します。コールバックが実行される前の最小遅延です。 。実際にかかる時間は、キュー内のそれより前のメッセージを処理するのにかかる時間によって異なります。
では、遅延が0
に設定されているとどうなりますか?新しいメッセージはすぐにキューに追加され、現在実行中のコードが終了し、以前に追加されたメッセージが処理されると処理されます。
setTimeout
…を呼び出すとき
setTimeout(function() {
console.log('AAA');
}, 0);
…指定されたコールバックでメッセージがキューに追加されます。コードの残りの部分…
for (i = 0; i < 1000; i++) {
console.log('BBB');
}
// etc.
…同期実行を継続します。完全に終了すると、イベントループは次のメッセージを求めてメッセージキューをポーリングし、setTimeout
コールバックを持つものを見つけて処理します(コールバックが実行されます)。
コールバックは、どれだけ時間がかかっても、現在実行中のコードが終了した後afterのみ実行されます。
イベントループの詳細については、以下を参照してください。