另一个异步循环中的Javascript异步循环
我在jQuery中有一些代码使用each()遍历div中的子级。 里面的每一个文本都被拆分成单词。每个单词都使用“for”循环进行处理。 此功能可能需要很长时间,并且会冻结浏览器,因此 有没有一种方法可以在另一个异步循环中创建异步循环,但其中一个正在等待另一个完成 谁能告诉我正确的方向吗 我想出了这样的办法:另一个异步循环中的Javascript异步循环,javascript,jquery,Javascript,Jquery,我在jQuery中有一些代码使用each()遍历div中的子级。 里面的每一个文本都被拆分成单词。每个单词都使用“for”循环进行处理。 此功能可能需要很长时间,并且会冻结浏览器,因此 有没有一种方法可以在另一个异步循环中创建异步循环,但其中一个正在等待另一个完成 谁能告诉我正确的方向吗 我想出了这样的办法: var queue = []; var nlevel = 0; function work() { nlevel = queue.length-1; var arr =
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);
});
});
var队列=[];
var nlevel=0;
职能工作(){
nlevel=queue.length-1;
var arr=队列[nlevel][0];
var进程=队列[nlevel][1];
var cnt=队列[nlevel][2];
var项目=arr[cnt];
过程。应用(项目);
cnt++;
队列[nlevel][2]=cnt;
if(碳纳米管<阵列长度){
设置超时(工作,1);
}否则{
如果(队列长度>1){
queue.pop();
设置超时(工作,1);
}
}
}
每个功能(arr、流程){
push([arr,process,0]);
设置超时(工作,1);
}
每个(['1','2','3'],函数(){
警惕(这个);
每个([1,2,3,4],函数(){
警惕(这个);
});
});
但是它有一些主要的错误,我无法修复。您可以使用Web Workers在后台线程中运行多个脚本。但并非所有浏览器都支持它们。请参阅Mozilla或simple ask Google的这篇文章:您可以使用Web Workers在后台线程中运行多个脚本。但并非所有浏览器都支持它们。请参阅Mozilla或simple ask Google的这篇文章:您可以定期使用
SetTimeout(0,…)
将控件“让渡”给浏览器,以防止冻结浏览器(但它不会执行得更快,事实上可能会稍微慢一点)
请参阅该技术的一个示例,如果不查看您的代码,我无法更具体地说明。您可以定期使用
SetTimeout(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);
一种方法是创建要处理的工作项队列:
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);
假设您当前的代码与此类似:
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);
}
});
工作演示:
doIteration()
函数通过适当地处理一些计数器并通过setTimeout()
调用自身来进行下一次迭代,从而模拟嵌套循环。包装整个过程的立即执行的匿名函数对流程来说并不是必不可少的,它只是用来限制变量的范围
是的,这可能会做得更好,但这正是我在运行中想到的-显然,您将根据自己的处理情况对其进行适当的修改
(如果您不关心单词的处理顺序,只要
processWord()
函数获得与每个单词相关联的i
和j
的正确值,就可以很容易地使其变得更整洁,但我没有时间做一个更整洁的版本来按顺序处理。)假设您当前的代码与此类似:
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);
}
});
工作演示:
doIteration()
函数通过适当地处理一些计数器并通过setTimeout()
调用自身来进行下一次迭代,从而模拟嵌套循环。包装整个过程的立即执行的匿名函数对流程来说并不是必不可少的,它只是用来限制变量的范围
是的,这可能会做得更好,但这正是我在运行中想到的-显然,您将根据自己的处理情况对其进行适当的修改
(如果您不关心单词的处理顺序,只要
processWord()
函数获得与每个单词相关的i
和j
的正确值,就可以轻松地将其变得更整洁,但我没有时间做一个更整洁的版本来按顺序处理。)我确信有一个解决方案,但是,如果没有看到您的实际代码,以及对代码中要更改的内容的详细描述,我们真的帮不了多少忙。我相信有一个解决方案,但是,如果没有看到您的实际代码和关于您希望更改代码内容的详细描述,我们就无法提供太多帮助。Jacob您的setTimeout
函数不应该将参数反转,以便先传递函数,然后再传递延迟吗?然后它将读取为setTimeout(processItemFromQueue,delayBetweenItems)代码>。引用:您的setTimeout
函数不应该反转参数,以便先传递函数,然后传递延迟吗?然后它将读取为setTimeout(processItemFromQueue,delayBetweenItems)代码>。参考文献