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/izumob/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 回答