我正在尝试创建一个需要预先形成大量循环的页面。使用while / for循环会导致页面挂起,直到循环完成,在这种情况下,循环可能会运行数小时。我也尝试过使用setTimeout,但这会达到递归限制。如何防止页面达到递归限制?
var looper = {
characters: 'abcdefghijklmnopqrstuvwxyz',
current: [0],
target: '',
max: 25,
setHash: function(hash) {
this.target = hash;
this.max = this.characters.length;
},
getString: function() {
string = '';
for (letter in this.current) {
string += this.characters[this.current[letter]];
}
return string;
},
hash: function() {
return Sha1.hash(this.getString());
},
increment: function() {
this.current[0] += 1;
if (this.current[0] > this.max) {
if (this.current.length == 1) {
this.current = [0, 0];
} else {
this.current[1] += 1;
this.current[0] = 0;
}
}
if (this.current[1] > this.max) {
if (this.current.length == 2) {
this.current[2] == 0;
} else {
this.current[3] += 1;
this.current[2] = 0;
}
}
},
loop: function() {
if (this.hash() == this.target) {
alert(this.getString());
} else {
this.increment();
setTimeout(this.loop(), 1);
}
}
}
答案 0 :(得分:3)
setInterval是常用的方法,但您也可以尝试使用web worker,这将比setInterval更简单地重构您的代码,但只适用于HTML5浏览器。
答案 1 :(得分:2)
您的setTimeout
没有做您认为正在做的事情。这是它正在做的事情:
遇到这句话:
setTimeout(this.loop(), 1);
它评估setTimeout
,this.loop()
的第一个参数。它会在那里调用loop
;它不会像你预期的那样等待一毫秒。
它会像这样调用setTimeout:
setTimeout(undefined, 1);
理论上,无论如何。实际上,第二步永远不会完成;它无限期地进行。您需要做的是传递对函数的引用而不是函数的返回值:
setTimeout(this.loop, 1);
然而,this
在下一个循环中将是window
,而不是looper
。绑定它,而不是:
setTimeout(this.loop.bind(this), 1);
答案 2 :(得分:1)
setInterval可能有用。它每隔一定时间调用一个函数。
例如
myInterval = setInterval(myFunction,5000);
这将每5秒调用一次你的函数(myFunction)。
答案 3 :(得分:1)
为什么不使用setInterval进行循环检查?
var loopWorking = false;
function looper(){
loopWorking = true;
//Do stuff
loopWorking = false;
}
function checkLooper()
{
if(loopWorking == false)
looper();
}
setInterval(checkLooper, 100); //every 100ms or lower. Can reduce down to 1ms
答案 4 :(得分:0)
如果您想避免递归,请不要从this.loop()
内部调用this.loop()
。而是使用window.setInterval()重复调用循环。
答案 5 :(得分:0)
我不得不在谷歌代码美化中手工编写延续传递方式。
基本上我转过来了
for (var i = 0, n = arr.length; i < n; ++i) {
processItem(i);
}
done();
到
var i = 0, n = arr.length;
function work() {
var t0 = +new Date;
while (i < n) {
processItem(i);
++i;
if (new Date - t0 > 100) {
setTimeout(work, 250);
return;
}
}
done();
}
work();
没有达到任何递归限制,因为没有递归函数调用。