こんばんは!本日はjQueryでよく利用する「setInterval」と「setTimeout」の小話をしたいと思います!
どちらもアニメーションループなどをさせたりする時に利用するものではありますが、やっている処理とかは同じようで微妙に違うんですね。
ボクはsetIntervalを時計、setTimeoutをタイマーという風に思っております。

setIntervalについて

ボクは基本的にこのsetIntervalの方をよく使います。というかほとんどこれ。

setIntervalのメリットとしては、

・確実にセットした時間でループしてくれる
・書き方がsetTimeoutよりシンプル(個人的にそう思っている)

といった所でしょうか。
書き方に関してはどちらも慣れれば同じなのですが、ボクは最初に使ったのがsetIntervalということもあって、すっかり慣れ親しんでいます。ちなみにセットした時間で確実にループをするっていうのは当たり前のようで当たり前ではない。これは後述します。

ちなみに書き方はこんな感じ

setInterval(function(){
    console.log("ループ中");
},1000);

引数1つ目に処理したい内容、2つ目にループさせる時間。
上の例だと1000ミリ秒(1秒)ごとにコンソールに文字を吐き出します。

見た感じこれでいーじゃん!って思ってもらえると思うのですが、一応落とし穴もあります。

・処理内容が終わっていなくても問答無用で時間通りに動く

これってかなり致命的になる可能性は秘めてるんですよね。利用しているパソコンによって処理速度も異なる訳であって、あんまり重たい処理をループさせると、処理がブラウザにどんどんドンドン溜まっていって、最悪クラッシュ…みたいな可能性もあるということです。

それはマズいよ!ちゃんと処理が終わってからループさせることは出来ないの!?

安心してください。それをやってくれるのがsetTimeoutです。

setTimeoutについて

先ほど上で述べた通り、setIntervalの問答無用ループに対し、setTimeoutは処理が終わってから次のループに入るようになっています。
これは完全なメリットになるかと。

ちなみに書き方はこんな感じ

function loop(){
    console.log("ループ中");
    setTimeout(loop,1000)
}
loop();

やってる内容はsetIntervalの例と同じで1000ミリ秒ごとにコンソールに文字を吐き出すという内容です。

こっちの方が処理もちゃんと実行するし良いんじゃね??って思う気持ちもわかります。
ただ、パーフェクトな人間はいない!というのと同じでコイツもパーフェクトではありません。

・ピッタリ指定した時間でループしない(4ミリ秒ずつくらいズレるらしい)

はい。これではHappy New Year!!!のカウントダウンタイマーをセットしてもズレてきてしまうので、まだ年明けてねーし!!みたいなツッコミをくらってしまいます。

一長一短って感じですが、どっちを使うのが良いんでしょうかね?

結局どっちがいいの?

これは完全にその人や、処理内容によって異なってくると思います。

ボクは処理がそこまで重くなるようなループを組まないので、大体setIntervalで問題ないと判断します。
canvasを動かす時はどっちにしようか悩みますが、それでもsetIntervalを使うことが多いです。

でも、こんなボクでもsetTimeoutを利用する時もあります。
さて、それはどういう時かと言うと

ループかける時はsetInterval
delay的な役割でsetTimeout

って感じです。
delay的なって意味がよくわからないと思うのですが、ボクは基本的にsetTimeoutでループ処理はしません。

実はsetIntervalでセットした時間の意味は◯◯秒ごとに処理を行う
setTimeoutでセットした時間は◯◯秒後に処理を行う

という違いを持っています。なので、上のsetTimeoutの例はloop()の中にloop()を一秒後に処理する命令を書いているので、見た目上ループしているように見えているのでございます。

逆に言えば、ループさせずに一回だけ利用するのも可能ということ。
fadeInとかfadeOutは.delay()で処理を遅らせたり、処理後の引数を渡すことが出来ますが、このdivの背景色が変化してからこっちのdivの背景色を変化させたいんだ!みたいなときは.delay()が使えない訳です。

そういう時にsetTimeoutで時間をずらしてあげると良いわけですね。CSSのanimationでもいいのですが…

まぁボクはこんな感じで使い分けをしております。

ループ解除方法

ところで、さっきの2つの例は無限ループなので、永久に処理が続くといったコードでした。
無限ループで良い場合もあるのですが、当然ある一定の条件でループを止めたい!なんて時もある訳です。
ちなみにループを止めるために、clearIntervalとclearTimeoutっていうのが用意されています。

ボクはこのループをストップさせるコードを中々覚えられなくて、何度も同じことで検索しました…
ちなみにボクがよくハマってたコードがこちら
(ボクはこれ使う時は必ず処理内容を別の所に書きます)

setInterval(loop,1000);
function loop(){
    console.log("ループ中");
}

$(".sample").click(function(){
    clearInterval(loop);
});

.sampleをクリックしたらループが止まるって処理を書きたい自分。

これで一見何の問題もなさそうに思うのだけれども、止まらない。一度動き出したループと恋は簡単には止まらない。

何回このコード書いては迷ったかわからんくらい迷いました…いい加減覚えろよって思っていたけど、なかなか覚えられなかった…
しかし、ある覚え方をしてから完璧に覚えられたので、今日はそれを共有。共有 for you。

・・・

ボクの覚え方、それは!!

何かを操作する時はリモコンを使うじゃないか!!

そう!名付けてリモコン方式!!

まぁ、どういうことかと言いますと、テレビとかの操作ってリモコン使いますよね?
そのリモコンを変数として作って、扱えば操作できるっていう発想です。

var rimokon; // ←これがリモコン

rimokon = setInterval(loop,1000);
function loop(){
    console.log("ループ中");
}

$(".sample").click(function(){
    clearInterval(rimokon);
});

セットする時もクリアする時もこのリモコンを使います。

まず、セットするには「変数名 = setInterval(処理,時間);」
そして、解除するには「clearInterval(変数名);」

こんな感じで覚えると簡単でした!(人による)

ちなみにclearTimeoutも発想は同じです

var rimokon;
 function loop(){
     console.log("ループ中");
     rimokon = setTimeout(loop,1000)
 }
 loop();

$(".sample").click(function(){
    clearTimeout(rimokon);
});

非常に便利なので、是非覚えてご活用くださいっ!!

という訳で今回はよく使うsetIntervalとsetTimeoutの小話でした!
ありがとうございました!