忍者ブログ
[PR]
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。



2017/12/16 06:49 |
JavaScript window.setIntervalに注意
JavaScriptで定期的に実行したい関数がある場合、window.setIntervalを使用することがあるかもしれません。
window.setIntervalは指定した時間毎に関数を実行してくれる便利な関数です。
で、うっかり関数内でsetIntervalを使用した場合、実際うまく動いているように見えることが多いので気付かないかもしれませんが、実は内部で恐ろしいことが起こっています。
<div id="hoge">
	<script type="text/javascript">hoge();</script>
</div>

<script type="text/javascript">
	function hoge(){
		$.get("hoge.php", function(data){
			$('#hoge').html(data);
			window.setInterval(hoge, 1000);
		});
	}
</script>
よくあるAJAXで自動的に更新されるHTMLです。
AJAXでhoge.phpを拾ってきて、<div>タグの中身を書き換え、インターバルをセットしています。
これでめでたしかと思いきや、ポイントはsetIntervalは重複するというところです。

どういうことかって、最初にHTMLを呼び出した時点でhoge()が実行され、setIntervalでhoge()が予約されます。
1秒後に予約されたhoge()が実行されます。
で、ここでsetIntervalでhoge()が予約されます。
2秒後には…最初に予約されたhoge()と1秒後に予約されたhoge()で2回のhoge()が実行されます。
で、ここでsetIntervalでhoge()が2回分予約され……

自分で書いたものとはいえ、サービスイン直前に見つけたときはどうしようかと思った。
いや、なんかうっかりsetIntervalとsetTimeoutを混同してしまっていたらしい。

というわけでこのような場合はsetTimeoutで実装します。
<div id="hoge">
	<script type="text/javascript">hoge();</script>
</div>

<script type="text/javascript">
	function hoge(){
		$.get("hoge.php", function(data){
			$('#hoge').html(data);
			window.setTimeout(hoge, 1000);
		});
	}
</script>
setTimeoutは指定時間後にただ一回だけ実行してくれる、という関数です。
これで毎秒一回関数が実行されるようになりました。

ちなみに、setIntervalを使う場合は以下のように関数の外に出します。
<div id="hoge">
	<script type="text/javascript">window.setInterval(hoge, 1000);</script>
</div>

<script type="text/javascript">
	function hoge(){
		$.get("hoge.php", function(data){
			$('#hoge').html(data);
		});
	}
</script>
こっちでも一応動くのですが、避けられるようであれば避けた方がいいです。
何故ならばsetIntervalは杓子定規に動くので、もし前の呼び出しが終了していなくてもさらに実行されてしまうのです。
10秒かかる処理をsetIntervalで実装してしまうと、同じ関数が同時に10本走ったりとかそういう事態になってたいへんです。

setIntervalは忘れてsetTimeoutを使いましょう。
PR


2012/04/20 23:23 | Comments(0) | JavaScript

コメント

コメントを投稿する






Vodafone絵文字 i-mode絵文字 Ezweb絵文字 (絵文字)



<<買ったものリスト 2012/04/22 | HOME | Minecraft1.1 MOD紹介 ThaumCraft 1.2.6 その8 タリスマン>>
忍者ブログ[PR]