使用setTimeout对数组进行Javascript递归循环?

时间:2017-03-02 19:35:42

标签: javascript arrays recursion

我在ES6中有这段代码:

function loopLettersEvery3Seconds() {
    const letters = ['a', 'b', 'c'];

    let offset = 0;
    letters.forEach((letter, index) => {
      setTimeout(() => {
        // I do something with the letter, nothing important
      }, 3000 + offset);
      offset += 3000;
      if (index === letters.length - 1) {
        loopLettersEvery3Seconds(letters);
      }
    });
}

这个函数循环遍历一个字母数组,每隔3秒我可以对每个字母做一些事情。但问题是,当这个循环结束并完成时,我不能再重复该过程......递归调用会产生堆栈溢出(Uncaught RangeError:超出最大调用堆栈大小)lol

告诉我该怎么做!谢谢!

BR

4 个答案:

答案 0 :(得分:2)

你可以这样做。这是通过递归和setTimeouts

模拟setInterval的方法
sudo /usr/bin/kafka-consumer-groups --zookeeper localhost:2181 --list

这样,你不必处理循环的同步特性,而是根据callstack和web api来做所有事情(是超时的正确术语吗?)

如果你想让它永远循环,那么就这样做

sudo /usr/bin/kafka-consumer-groups --new-consumer --bootstrap-server localhost:9092 --list

答案 1 :(得分:1)

forEach是同步的。你在设置了最后一次超时之后立即进行了递归调用,这显然会在函数调用自身时导致堆栈溢出而没有基本情况停止。

对于永久运行的动画,您需要在最后一次超时中将“递归”调用放在中:

function loopLettersEvery3Seconds() {
  ['a', 'b', 'c'].forEach((letter, index) => {
    setTimeout(() => {
      // I do something with the letter, nothing important
      if (index === letters.length - 1) {
        loopLettersEvery3Seconds(letters);
      }
    }, 3000 * (index + 1));
  });
}

答案 2 :(得分:0)

您应该使用setTimeout代替offset,这样可以避免使用%变量。请注意,您可以使用模(function loopLettersEvery3Seconds() { const letters = ['a', 'b', 'c'] let index = 0 setInterval(() => { console.log(letters[index]) index = (index + 1) % letters.length }, 3000) } loopLettersEvery3Seconds())运算符来确保索引在递增时“循环”:

invoice i

答案 3 :(得分:0)

我想在这种情况下,准递归循环是最好的;



var chars = ["a","b","c"];

function loop(a,i = 0){
  console.log(a[i%a.length]);
  setTimeout(loop,1000,a,++i);
}

loop(chars);