Javascriptのプログラムで、常に特定の変数を監視する処理をsetInterval()を使用して実装した際の話。
本当はsetInterval()を使用すべきでないのも、Reactを使用すればStateで自動で処理してくれるのもわかってはいるのですが、今回はもろもろの都合でこの方法をとることにしました。
さて、最初僕は下記のように記述していました。
1 2 3 4 5 6 7 8 9 | setInterval(loadingIconSwitcher(), 100); function loadingIconSwitcher() { if (!ajax_status || !prev_photo_ajax_status || !upload_status) { //条件の変数はすべてboolの値が入る $( "#loading" ).css( "display" , "block" ); } else { $( "#loading" ).css( "display" , "none" ); } } |
3つの変数のうち、いずれかでもfalseになれば読み込み中のloadingアイコンを表示し、すべてtrueになったら消す、というプログラムをsetIntervalで100ミリ秒ごとに回して疑似的に変数を監視するのが目的です。
もうお分かりの方もいるかと思いますが、上記のコード、正常に動作しません。
実際に動かしたところ、なぜか一度だけ”loadingIconSwitcher()”が動いて止まるだけです。
最初、なぜループされないのか全く分からずいろいろ調べたところ、こちらの記事を発見。
setInterval()の盲点::JavaScript – カニとモモンガと愉快なユウ
この記事を見て思い出しましたが、このsetInterval()という関数で、第一引数に指定する関数を”文字列”で渡さないといけないことになっています。
つまり、上記の例だと
1 | setInterval( "loadingIconSwitcher()" , 100); |
とするのが正解です。
こちらに直したところ、意図した通り100ミリ秒ごとに動いてくれるようになりました。
しかし関数名をなぜ文字列で渡すのか…正直納得がいきませんが…
ということで、setInterval()関数を使う方はご注意ください。