Now browsing the archives for the 'JavaScript' category.

非同期ループ処理 (4) - 進捗表示1

非同期ループ処理 (3) に、配列の長さ _length と現在の処理数 _count を追加した。
これによってプログレスバーなどで進捗状況を表示できるようになる。

var asyncProgressiveProcessor = {

    _count  : 0,
    _length : 0,
    _array : [],

    start : function(aArray)
    {
        // 開始処理
        dump("start
");
        // 初期化
        this._array = aArray;
        this._count = 0;
        this._length = this._array.length;
        this._next();
    },

    _next : function()
    {
        var elt = this._array.shift();
        if ( elt ) {
            this._count++;
            setTimeout(function(){ asyncProgressiveProcessor._process(elt); }, 500);
        } else {
            setTimeout(function(){ asyncProgressiveProcessor._finish(); }, 500);
        }
    },

    _process : function(aElt)
    {
        // 処理
        dump("processing (" + this._count + "/" + this._length + ")... " + aElt + "
");
        // 次の処理へ
        this._next();
    },

    _finish : function()
    {
        // 終了処理
        dump("finish
");
    },

};

asyncProgressiveProcessor.start(['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']);

TOP

非同期ループ処理 (3)

非同期ループ処理 (2) とあまり変わらないが、次の処理へ進む部分を _next として切り分けており、より見やすくなっている。

var asyncProcessor = {

    _array : [],

    start : function(aArray)
    {
        // 開始処理
        dump("start
");
        // 初期化
        this._array = aArray;
        this._next();
    },

    _next : function()
    {
        var elt = this._array.shift();
        if ( elt ) {
            setTimeout(function(){ asyncProcessor._process(elt); }, 500);
        } else {
            setTimeout(function(){ asyncProcessor._finish(); }, 500);
        }
    },

    _process : function(aElt)
    {
        // 処理
        dump("processing... " + aElt + "
");
        // 次の処理へ
        this._next();
    },

    _finish : function()
    {
        // 終了処理
        dump("finish
");
    },

};

asyncProcessor.start(['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']);

TOP

非同期ループ処理 (2)

開始処理~処理~終了処理という形で見やすく切り分けた方法。

var simpleAsyncProcessor = {

    _array : [],

    start : function(aArray)
    {
        // 開始処理
        dump("start
");
        // 初期化
        this._array = aArray;
        this._process();
    },

    _process : function()
    {
        var elt = this._array.shift();
        if ( !elt ) {
            simpleAsyncProcessor._finish();
            return;
        }
        // 処理
        dump("processing... " + elt + "
");
        // 次の処理へ
        setTimeout(function(){ simpleAsyncProcessor._process(); }, 500);
    },

    _finish : function()
    {
        // 終了処理
        dump("finish
");
    },

};

simpleAsyncProcessor.start(['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']);

TOP

非同期ループ処理 (1)

要素数が多い配列に対して順番に処理を行うような場合に、 for や while で単純にループさせると、処理が終わるまでに一時的な無応答状態に陥ってしまう、あるいは時間がかかりすぎてスクリプトを続行するかどうかの警告が表示されてしまうことがある。

そこで、setTimeoutを連発してこれを防ぐ。

まずは、対象となる配列を引数に再帰的に関数を呼び出す方法。
なお、下記の例では確認しやすいように500ミリ秒後に次の処理へ進むが、実際は0ミリ秒で構わない。

function processRecursive(aArray)
{
    var elt = aArray.shift();
    if ( elt ) {
        // 処理
        dump("processing... " + elt + "
");
        setTimeout(function(){ processRecursive(aArray); }, 500);
    } else {
        // 終了処理
        dump("finish
");
    }
}

processRecursive(['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']);

TOP