我在jQuery中有一些代码使用each()遍历div中的子代。 里面的每个文本都被分成了单词。每个单词都用'for'循环处理。 此功能可能需要很长时间,因此可以冻结浏览器......
有没有办法在另一个异步循环中创建异步循环,但是有人在等待其他循环完成?
有人能告诉我正确的方向吗?
我想出了类似的东西:
var queue = [];
var nlevel = 0;
function work() {
nlevel = queue.length-1;
var arr = queue[nlevel][0];
var process = queue[nlevel][1];
var cnt = queue[nlevel][2];
var item = arr[cnt];
process.apply(item);
cnt++;
queue[nlevel][2] = cnt;
if (cnt < arr.length) {
setTimeout(work, 1);
} else {
if (queue.length>1) {
queue.pop();
setTimeout(work, 1);
}
}
}
function each(arr, process) {
queue.push([arr, process, 0]);
setTimeout(work, 1);
}
each(['one', 'two', 'three'], function() {
alert(this);
each([1, 2, 3, 4], function() {
alert(this);
});
});
但它有一些重大错误,我无法解决它。
答案 0 :(得分:3)
您可以使用Web Workers在后台线程中运行多个脚本。但是在每个浏览器中都不支持它们。请参阅Mozilla的这篇文章或简单问Google:https://developer.mozilla.org/En/Using_web_workers
答案 1 :(得分:1)
您可以定期使用SetTimeout(0,...)
来“控制”浏览器控制,以防止冻结浏览器(但它不会执行得更快,实际上它可能会稍慢)。
有关该技术的示例,请参阅this answer,如果没有看到您的代码,我就无法更具体。
答案 2 :(得分:0)
您可以这样做的一种方法是创建要处理的工作项队列:
var queue = [];
将要处理的项目放在此队列中,而不是立即处理:
queue.push(item);
然后启动一个定时器循环来处理项目:
var delayBetweenItems = 10;
var processItemFromQueue = function() {
if (queue.length) {
item = queue.shift();
doStuff(item);
setTimeout(delayBetweenItems, processItemFromQueue);
}
};
setTimeout(processItemFromQueue, delayBetweenItems);
答案 3 :(得分:0)
假设您当前的代码类似于此:
function processWord(word, i, j) {
// do something with the current word, where
// (if it's needed) i is the index into the elements
// and j is the index into the current element's words
}
$("#divId").children().each(function(i) {
var words = $(this).text().split(" "),
j;
for(j = 0; j < words.length; j++) {
processWord(words[j], i, j);
}
});
你可以用setTimeout()
重写那个外部(i)和内部(j)循环:
// assumes the same processWord() function as above
(function (){
var $items = $("#divId").children(),
words,
i, j,
iMax, jMax;
function doIteration() {
if (j === jMax) {
if (++i === iMax)
return;
// outer loop processing
words = $($items[i]).text().split(" ");
jMax = words.length;
j = 0;
}
if (j < jMax) {
// inner loop processing
processWord(words[j], i, j);
j++;
}
setTimeout(doIteration, 1);
}
iMax = $items.length;
i = j = jMax = -1;
doIteration();
})();
工作演示:http://jsfiddle.net/sp8Wr/
doIteration()
函数通过适当处理一些计数器并通过setTimeout()
调用自身来进行下一次迭代来模拟嵌套循环。包含整个事物的立即执行的匿名函数对于该过程来说并不重要,它只是限制变量的范围。
是的,这可能会做得更好,但这正是我动态想出的 - 显然你会根据自己的处理进行修改。
(只要processWord()
函数获得与每个单词关联的i
和j
的正确值,您就不在乎处理单词的处理顺序可以很容易地使很多更整洁,但我没有时间做一个整洁的版本按顺序处理。)