ひとモノBLOG

04 « 2017 / 05 » 06
Sun Mon Tue Wed Thu Fri Sat
- 1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31 - - -
profile
SHOO
  • SHOO
  • 機械系の学生。の割にプログラミングとかのほうが得意だったり。
  • RSS
links
BLOG内検索
Adds by DTI Blog

FirefoxのGreasemonkey用にJavascriptの小物
2008/06/22(日) [18:18:31]

自分用メモ的に…

JavascriptはSleepとかがない!
これが困るんだ。特に非同期なsetTimeoutとか、XMLHttpRequestのopenの第三引数にtrueを指定したりすると、それが終了したときに実行する関数を設定して、シーケンシャルな動作をさせたりするのに、慣れないからかどうしても汚らしいコードになってしまう。

そんな悩みを解決するため、非同期関数をシーケンシャルな動作にするためのオブジェクトを考えてみたりした。

主にGreasemonkeyなんかで使えるんじゃないかと。

これがそのHTMLコード。

以下にコードを示します。

<html>
    <head>
<script type="application/javascript;version=1.8">
    
</script>
    </head>
    <body>
        <pre id="traceLayer"></pre>
        <hr/>
        <pre id="printLayer"></pre>
        <script>
function fixString(str){return str ? str.toString(): str == undefined ? "[undefined]": str == null ? "[null]": str.toString();}
function trace(str){document.getElementById("traceLayer").innerHTML = fixString(str);}
function print(str){with(document.getElementById("printLayer"))innerHTML = innerHTML + fixString(str);}
function println(str){print(str.toString());print("rn");}
(function(){
////////////////////////////////////////////////////////////////////////////////

    ////////////////////////////////////////////////////////////////////////////
    /// 定期的に関数を呼び出す。
    /// interval で呼び出す間隔を決める
    /// func に呼び出す関数をセット
    /// data に関数を呼び出した際の引数をセット
    /// exec() で関数スタート
    /// exec(end) という感じに、endに関数を設定すると、終了時に通知する。
    var TimerFunc = function()
    {
        this.interval = 100;
        this.func = null;
        this.data = null;
        this.exec = function(end)
        {
            var self = this;
            if (this.func == null)
            {
                end();
                return false;
            }
            if (this.func(this.data) == false)
            {
                setTimeout(function(){self.exec(end);}, this.interval);
            }
            else if (end) end();
        };
    };
    
    ////////////////////////////////////////////////////////////////////////////
    /// シーケンシャルに非同期関数を呼び出していく
    /// threads の配列に呼び出す関数をセットしていく
    /// threads にセットする関数は必ず引数にend関数を受け取り、
    /// 処理の終了時にend()として終了したことを通知する必要がある。
    /// exec(end) という感じに実行、endに関数を設定すると、終了時に通知。
    var SequentialAsyncThreads = function()
    {
        this.threads = new Array;
        this.exec = function(end)
        {
            var self = this;
            if (self.threads.length)
            {
                var nextFunc = self.threads.shift();
                nextFunc(function(){self.exec();});
            }
            else if (end) end();
        };
    };
    ////////////////////////////////////////////////////////////////////////////
    /// 同時進行的に非同期関数を呼び出していく
    /// threads の配列に呼び出す関数をセットしていく
    /// threads にセットする関数は必ず引数にend関数を受け取り、
    /// 処理の終了時にend()として終了したことを通知する必要がある。
    /// exec(end) という感じに実行、endに関数を設定すると、全て終了時に通知。
    var ParallelAsyncThreads = function()
    {
        this.threads = new Array;
        this.m_EndedCount = 0;
        this.exec = function(end)
        {
            var self = this;
            for (var i=0; i < self.threads.length; ++i)
            {
                self.threads[i](function()
                {
                    ++self.m_EndedCount;
                    if (self.m_EndedCount == self.threads.length)
                    {
                        if (end) end();
                    }
                });
            }
        };
    };
    
    var st = new SequentialAsyncThreads;
    st.threads.push(function(end)
    {
        trace("exec A");
        setTimeout(function(){println("A"); end(); }, 1000);
    });
    st.threads.push(function(end)
    {
        trace("exec B");
        setTimeout(function(){println("B"); end(); }, 1000);
    });
    st.threads.push(function(end)
    {
        trace("exec C");
        setTimeout(function(){println("C"); end(); }, 1000);
    });
    
    var pt = new ParallelAsyncThreads;
    pt.threads.push(function(end)
    {
        trace("exec D");
        setTimeout(function(){println("D"); end(); }, 3000);
    });
    pt.threads.push(function(end)
    {
        trace("exec E");
        setTimeout(function(){println("E"); end(); }, 4000);
    });
    pt.threads.push(function(end)
    {
        trace("exec F");
        setTimeout(function(){println("F"); end(); }, 5000);
    });
    st.threads.push(function(end){pt.exec(end);});
    st.threads.push(function(end)
    {
        var tm = new TimerFunc;
        tm.interval = 500;
        tm.data = {i:0};
        tm.func = function(data){ ++data.i; trace(10-data.i); return data.i >= 10; };
        tm.exec(end);
    });
    st.threads.push(function(end)
    {
        trace("exec Goal");
        setTimeout(function(){println("Goal"); end(); }, 1000);
    });
    st.exec();
////////////////////////////////////////////////////////////////////////////////
})();
        </script>
    </body>
</html>


あー、どうでもいいけど、GinnieのHTML変換楽だわー…ちょっとごみが大量に混じるのが難点か…


rel="prev"<<Firefox3 keyconfig用検索バーのトグル動作用スクリプト | ホーム |

この記事に対するトラックバック

この記事のトラックバックURL

-

管理人の承認後に表示されます

  • From: |
  • 2013/04/26(金) 14:31:32

この記事に対するコメント

この記事にコメントする

管理者にだけ表示を許可する
| HOME |