タイマー処理系のJavaScriptについてまとめ
- 2013-10-24
- Javascript, setInterval, setTimeout, タイマー処理

photo by Mo Riza
タイマー処理系のJavaScriptについて、ちょっとこんがらがってきたので…
自分用のメモとしてまとめてみました。
目次
タイマー処理のJavaScriptは2種類
setTimeoutメソッド
指定した時間が経った後に、何らかの処理をする。
setTimeout(function(){ //do something }, 1000);
例えば1000ミリ秒後(1秒後)に何らかの処理をしたい場合はこんな感じで書く。
<!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <title>setTimeoutメソッドについて</title> </head> <body> <script> setTimeout(function(){ document.write("3秒経ちましたよ(*´∀`)"); }, 3000); </script> </body> </html>
setIntervalメソッド
一定の周期ごとに何らかの処理を繰り返す。
setInterval(function(){ //do something }, 1000);
例えば1000ミリ秒(1秒)ごとに何らかの処理を繰り返したい場合はこんな感じで書く。
<!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <title>setIntervalメソッドについて</title> </head> <body> <script> var i = 0; setInterval(function(){ document.write(i + "秒<br>"); i++; }, 1000); </script> </body> </html>
setTimeoutとsetIntervalの大きな違い、setIntervalをsetTimeoutで書き換える方法
- setTimeoutメソッドは前回の処理が終わったかどうか?を考慮する
- setIntervalメソッドは前回の処理が終わったかどうか?を考慮しない
つまり・・・
setInterval(function(){ //ここで1秒以上の時間がかかる処理が行われると、前回の処理が終わってないのにどんどんタスクが振ってきてブラウザがクラッシュする! }, 1000);
この問題を回避するためにsetIntervalを使わず…前回の処理が終わったかどうか考慮してくれるsetTimeoutで書き換えて使う。
先ほどのsetIntervalのデモソースをsetTimeoutを使って書き換えると・・・
<!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <title>setIntervalメソッドについて</title> </head> <body> <script> var i = 0; function countUp() { document.write(i + "秒<br>"); i++; setTimeout(countUp, 1000); } countUp(); </script> </body> </html>
こんな感じかな。試しにこの書き換えた物を実行してみると…あれれ、0秒目と1秒目が何故か改行されず…あとの秒数はきれいに改行されてるけど…なんでだろう?多少挙動が変わってるけど、、、まぁいいやw 細かいことは気にしないw
setIntervalで作るJSをsetTimeoutで書き換える時の公式
function functionName() { //do something setTimeout(functionName, 1000); } functionName();
1秒ごとに何らかの処理を繰り返す処理をsetTimeoutメソッドで書く方法はこんな感じかな。とりあえず関数を作って、その中に繰り返したい処理を書く。関数内部の最後にsetTimeoutを入れて…setTimeoutが実行するタイムアウト関数にはとりあえず作った関数名を入れる感じ。関数の中でその関数を使う…これがうわさの?帰納的?再帰的ってやつでしょうか?数学苦手なのでよく分かりませんが(;´∀`)
補足…3行目ですがsetTimeout(functionName(), 1000);
こんな風にsetTimeoutの引数として取るタイムアウト関数名に括弧をつけちゃうと…ブラウザがクラッシュしたり、スクリプトが上手く動かないですね。
一方で…setTimeout("functionName()", 1000);
こんな風にタイムアウト関数を引用符で囲ってあげると…キチンと動きます。
setTimeoutやsetIntervalを途中で止める方法
var i = 0; setInterval(function(){ console.log(i++); //コンソールに1秒ごと0から順番にカウントアップする数字を表示 }, 1000);
ためしにこんな感じのスクリプトを作って実行すると、コンソール(Google Chromeでctrl+shift+j
)に0から順番に数字がカウントアップしていきますよね。ほっといたらどんどんカウントアップしていきますが、これを数字の3で止めたいと思います。
var i = 0; var intervalId = setInterval(function(){ console.log(i++); //コンソールに1秒ごと0から順番にカウントアップする数字を表示 if(i > 3) { clearInterval(intervalId); } }, 1000);
こんな感じにすると3でピッタリ止まります。
ポイントは以下の3つ。
- setInterval内部にif文を入れる
- setInterval内部のifの中に…
clearInterval()
メソッドを入れて、その引数に適当な変数名を入れる - setInterval全体をその変数に保存する
変数名は適当にintervalIdとしてますが、何でも良いです。
timerIdでも、stopIdでも。
それでは次にこのsetIntervalをsetTimeoutで書き換えて、これを数字の3で止めてみましょう。
var i = 0; function countUp() { console.log(i++); var stopId = setTimeout(countUp, 1000); if(i > 3) { clearTimeout(stopId); } } countUp();
こんな感じですかね。setTimeout全体を変数に保存して、すぐ下の行にif文を、その中にclearTimeoutメソッドを入れて、引数に先ほどの変数名を指定する。
この記事のまとめ
やっぱり一番難しい、忘れやすいところはsetIntervalをsetTimeoutで書き換えるところかな?関数の中でその関数を呼び出す…再帰的、いや帰納的?関数っていうのが…数学苦手な自分にとってはピンとこないのですが、まぁこの辺は慣れるしかないですかね??(;^ω^)
コメント