tohokuaikiのチラシの裏

技術的ネタとか。

勝手に再帰するsetTimeoutなJavaScript

何かのタイミングで1回だけ実行するJavaScript。なんつーか、想定としては、Observerの順番を気にしなくてもいいように、「あるObject Aが作られたらBをnewしてInitializeする」っていう状況。

とりあえず、この関数だけ最初にParseしてくれれば後はObserveされるときに必要なObjectがあるかどうかで、無かったらN秒後にまたやってくれっていう。

サンプルコード

<html>
<script>
var $ = function(ele){return document.getElementById(ele);}; // s.c

var intervalDo = function(exec){
    var interval = 200;
    if (arguments[1] && parseInt(arguments[1])){
        interval = parseInt(arguments[1]);
    }
    var counter = 0;
    var ref_f = function(){
        setTimeout(
            function(e)
            {
                if ($('someone').value==""){
                    counter++;
                    $('counter').innerHTML = counter;
                    ref_f();
                } else {
                    exec();
                    $('counter').innerHTML += 'stop';
                }
            },interval);
    }
    ref_f();
};

var executeFunc = function(){alert("Execute!")};
intervalDo(executeFunc, 1000);
</script>
<body bgcolor="#cccccc">
<div id="counter"></div>
<input type="text" id="someone">
</body>
</html>

サンプル実行

実行したsetTimeoutの回数がカウントアップされて、テキストフィールドに文字が何か入ると指定した関数executeFuncが実行されるっていう。

あー、引数指定とか欲しいよね

2つ目の引数にsetTimeoutのIntervalをやってるから3つ目の引数以降があれば実行時に実行関数に与えるとか。

でも、これって汎用化はできんか。

どのタイミングで、次のsetTimeoutを辞めるかっていうロジックがこの中に入ってるから匿名関数にした方がいいよね。

すると、こんな感じか。

var executeFunc = function(){alert("Execute!")};
(function(exec){
    var interval = 200;
    var ref_f = function(){
        setTimeout(
            function(e)
            {
                if ($('someone').value==""){
                    ref_f();
                } else {
                    exec();
                }
            },interval);
    }
    ref_f();
})(executeFunc);