所以,我想循环遍历数百个项目,而不是在我处理每个项目时阻止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似乎不会产生或提供更改暂停时间的选项。
答案 0 :(得分: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');
});
答案 1 :(得分: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);
}