JavaScript の似て非なる2つの関数: setTimeout と setInterval。この2つの違いは分かりますか?
まず、どちらの関数も第一引数が実行する関数、第二引数が実行までの時間(ミリ秒)、という同じようなパラメータで使います:
上記2つのページの違いは事実上一箇所です。上は <body> のロード時に setTimeout を、下は <body> のロード時に setInterval を実行しています(そして繰り返し呼ばれます)。この2つがどのような挙動の違いになるか、わかりますか?
説明しやすいのは上の setTimeout を使った場合です。こちらは最初のロード時にまず func() 関数が呼ばれ、 その中で setTimeout を使って1秒後にもう一度 func() 関数が呼ばれ、・・・ という具合に、1秒おきに func() 関数が呼ばれるような処理になります:
一方、ちょっとわかりにくいのは下の setInterval を使った場合です。こちらは最初のロード時にまず func() 関数が呼ばれ(ここまでは同じ)、その中で setInterval を使って1秒毎に func() 関数が呼ばれるよう指定されています。そして1秒後に func() 関数が呼ばれると、再度1秒毎に func() 関数を呼ぶよう指定されます。そのため更に1秒経過すると、最初に指定された1秒おきの func() と、2回目に指定された1秒おきの func() と、都合2回 func() 関数が(ほぼ同時に)呼び出されることになります。そして2つそれぞれの func() の中で更に1秒毎に func() 関数を呼ぶよう指定されます。ということは更に1秒経過すると、最初に指定された1秒おきの func() と、2回目に指定された1秒おきの func() と、3回目に指定された1秒おきの func() が2回、都合4回 func() 関数がほぼ同時に呼び出されることになります:
この違い分かりますか?つまり setTimeout は次の1回の実行タイミングを指定しているのに対して、setInterval は何秒おきに実行するのかを指定している、ということになります。既に何秒おきに実行するのか設定されている状態で上書きしても、その前の指定がキャンセルされるわけではなく上書き(マルチスレッドのスレッドが1つ増える感じ)で実行タイミングがセットされるので、上記コードのようにループの中で何度も setInterval を実行すると、どんどん実行回数が増えていくことになる、という点に注意してください。
なお、setInterval を停止するには clearInterval 関数を実行します。
まず、どちらの関数も第一引数が実行する関数、第二引数が実行までの時間(ミリ秒)、という同じようなパラメータで使います:
<!-- setTimeout の場合 -->
<html>
<head>
<title>setTimeout</title>
<script>
var cnt = 0;
function func(){
cnt ++;
console.log( "cnt = " + cnt );
setTimeout( "func()", 1000 );
}
</script>
</head>
<body load="func()">
</body>
</html>
<!-- setInterval の場合 -->
<html>
<head>
<title>setInterval</title>
<script>
var cnt = 0;
function func(){
cnt ++;
console.log( "cnt = " + cnt );
setInterval( "func()", 1000 );
}
</script>
</head>
<body load="func()">
</body>
</html>
上記2つのページの違いは事実上一箇所です。上は <body> のロード時に setTimeout を、下は <body> のロード時に setInterval を実行しています(そして繰り返し呼ばれます)。この2つがどのような挙動の違いになるか、わかりますか?
説明しやすいのは上の setTimeout を使った場合です。こちらは最初のロード時にまず func() 関数が呼ばれ、 その中で setTimeout を使って1秒後にもう一度 func() 関数が呼ばれ、・・・ という具合に、1秒おきに func() 関数が呼ばれるような処理になります:
一方、ちょっとわかりにくいのは下の setInterval を使った場合です。こちらは最初のロード時にまず func() 関数が呼ばれ(ここまでは同じ)、その中で setInterval を使って1秒毎に func() 関数が呼ばれるよう指定されています。そして1秒後に func() 関数が呼ばれると、再度1秒毎に func() 関数を呼ぶよう指定されます。そのため更に1秒経過すると、最初に指定された1秒おきの func() と、2回目に指定された1秒おきの func() と、都合2回 func() 関数が(ほぼ同時に)呼び出されることになります。そして2つそれぞれの func() の中で更に1秒毎に func() 関数を呼ぶよう指定されます。ということは更に1秒経過すると、最初に指定された1秒おきの func() と、2回目に指定された1秒おきの func() と、3回目に指定された1秒おきの func() が2回、都合4回 func() 関数がほぼ同時に呼び出されることになります:
この違い分かりますか?つまり setTimeout は次の1回の実行タイミングを指定しているのに対して、setInterval は何秒おきに実行するのかを指定している、ということになります。既に何秒おきに実行するのか設定されている状態で上書きしても、その前の指定がキャンセルされるわけではなく上書き(マルチスレッドのスレッドが1つ増える感じ)で実行タイミングがセットされるので、上記コードのようにループの中で何度も setInterval を実行すると、どんどん実行回数が増えていくことになる、という点に注意してください。
なお、setInterval を停止するには clearInterval 関数を実行します。