不用while就创建一个JavaScript循环

时间:2011-06-24 01:42:21

标签: javascript

我正在尝试创建一个需要预先形成大量循环的页面。使用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);
    }
    }
}

6 个答案:

答案 0 :(得分:3)

setInterval是常用的方法,但您也可以尝试使用web worker,这将比setInterval更简单地重构您的代码,但只适用于HTML5浏览器。

http://dev.w3.org/html5/workers/

答案 1 :(得分:2)

您的setTimeout没有做您认为正在做的事情。这是它正在做的事情:

  1. 遇到这句话:

    setTimeout(this.loop(), 1);
    
  2. 它评估setTimeoutthis.loop()的第一个参数。它会在那里调用loop;它不会像你预期的那样等待一毫秒。

  3. 它会像这样调用setTimeout:

    setTimeout(undefined, 1);
    
  4. 理论上,无论如何。实际上,第二步永远不会完成;它无限期地进行。您需要做的是传递对函数的引用而不是函数的返回值:

    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();

没有达到任何递归限制,因为没有递归函数调用。