違いはありますか?
はい。Timeout は、setTimeout() が呼び出された後、一定時間実行されます。Interval は、前の間隔が起動された後、一定の時間実行されます。
doStuff() 関数の実行に時間がかかる場合、違いに気付くでしょう。たとえば、setTimeout/setInterval の呼び出しを で表し、.
タイムアウト/間隔の起動を で表し、 *
JavaScript コードの実行をで表すと[-----]
、タイムラインは次のようになります。
Timeout:
. * . * . * . * .
[--] [--] [--] [--]
Interval:
. * * * * * *
[--] [--] [--] [--] [--] [--]
次の複雑な点は、JavaScript が何か (前の間隔の処理など) で既にビジー状態である間に間隔が発生した場合です。この場合、間隔が記憶され、前のハンドラーが終了してブラウザーに制御が戻るとすぐに発生します。たとえば、短い ([-]) ときも長い ([-----]) ときもある doStuff() プロセスの場合:
. * * • * • * *
[-] [-----][-][-----][-][-] [-]
• は、そのコードをすぐに実行できず、代わりに保留になった間隔発火を表します。
そのため、間隔はスケジュールに戻るために「追いつく」ようにします。ただし、それらは互いに重ねてキューに入れません。間隔ごとに保留中の実行は 1 つだけです。(それらがすべてキューに入れられた場合、ブラウザーには未処理の実行の拡大し続けるリストが残されます!)
. * • • x • • x
[------][------][------][------]
x は、実行または保留にできなかったため、代わりに破棄された間隔発火を表します。
doStuff() 関数の実行に設定された間隔よりも長い時間がかかる場合、ブラウザはそれを処理しようとして 100% の CPU を消費し、応答が遅くなる可能性があります。
どちらを使用し、その理由は何ですか?
Chained-Timeout は、ブラウザーに空き時間のスロットを保証します。Interval は、ブラウザー UI の可用性を犠牲にして、実行中の関数がスケジュールされた時間にできるだけ近く実行されるようにします。
可能な限りスムーズにしたい 1 回限りのアニメーションの間隔を検討しますが、ページが読み込まれている間に常に発生する進行中のアニメーションには、連鎖したタイムアウトの方が丁寧です。要求の少ない用途 (30 秒ごとに起動する単純なアップデーターなど) では、どちらも安全に使用できます。
ブラウザーの互換性に関しては、setTimeout は setInterval より前から存在しますが、現在遭遇するすべてのブラウザーは両方をサポートしています。長年の最後のストラグラーは、WinMo 6.5 未満の IE Mobile でしたが、それも今や私たちの背後にあることを願っています。