2

したがって、数百のアイテムをループ処理し、それぞれを処理している間は UI スレッドをブロックしたくありません。おそらく数秒の作業なので、頻繁に譲りたいと思います。いくつかの本は、次のようなループを推奨しています。

function processArray(items, process, callback){
    var todo = items.concat(); //create a clone of the original
    setTimeout(function () {
        process(todo.shift());
        if (todo.length > 0) {
            setTimeout(arguments.callee, 100);
        } else {
            callback(items);
        }
    }, 100);
}

(参照http://answers.oreilly.com/topic/1506-yielding-with-javascript-timers/ )

前回、巧妙なループを使用したとき、アンダースコアが既にそれをサポートしており、おそらくより優れた、より安定したバージョンなどがあることがわかりました。アンダースコアで上記を行うにはどうすればよいですか? _.each は適用されないようです。_.each は一時停止時間を変更するためのオプションを生成または提供していないようです。

4

2 に答える 2

2

非同期ライブラリ
https://github.com/caolan/asyncを調べて、コールバックを受け入れる非同期関数を
作成します。process

function process(item, cb){
    //replace this code block with your actual process logic
    setTimeout(function () {console.log(item); async.nextTick(cb);}, 500);
}
function processArray(items, iterator, callback){
    var todo = items.concat(); //create a clone of the original
    async.eachLimit(todo, 4, iterator, function(){ 
        //replace 4 with the desired number of simultaneous asynchronous operations
        //if `process` isn't too computationally expensive, you could try 50 
        callback(); //all done
    });
}

processArray([0,1,2,3,4,5,6,7,8,9,10], process, function(){
    console.log('all done');
});

デモ: http://jsbin.com/izmob/1/

于 2013-06-20T14:04:37.920 に答える
0

代わりに間隔を使用することをお勧めします。そうすれば、繰り返し呼び出すことはなくsetTimeout、反復ごとに無名関数を構築することもできません。

function processArray(items, process, callback) {
  var todo = items.concat();

  //our interval "loop"
  var loop = setInterval(function () {

    process(todo.shift());

    //"break" the interval when nothing left
    if(!todo.length) {
      clearInterval(loop);
      callback(items);
    }
  }, 100);
}
于 2013-06-20T14:00:58.403 に答える