Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/471.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带setTimeout的数组上的Javascript递归循环?_Javascript_Arrays_Recursion - Fatal编程技术网

带setTimeout的数组上的Javascript递归循环?

带setTimeout的数组上的Javascript递归循环?,javascript,arrays,recursion,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 },

我在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秒钟我就可以对每个字母做一些事情。但问题是,当这个循环结束时,我不能再重复这个过程。。。递归调用生成堆栈溢出(未捕获范围错误:超过最大调用堆栈大小)lol

告诉我怎么做!谢谢


BR

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

您可能应该使用
setInterval
而不是
setTimeout
,这样可以避免使用
offset
变量。请注意,您可以使用模(
%
)运算符来确保索引在递增时“循环”:

函数loopLettersEvery3Seconds(){
常量字母=['a','b','c']
设指数=0
设置间隔(()=>{
console.log(字母[索引])
索引=(索引+1)%letters.length
}, 3000)
}

loopLettersEvery3Seconds()
您可以这样做。这就是如何通过递归和设置超时来模拟设置间隔

var array = ['a', 'b', 'c']

function loopLettersEvery3Seconds(arr, index) {
    if (index === arr.length) return;
    //Do stuff with array
    setTimeout(loopLettersEvery3Seconds, 3000, arr, index+1)
}
loopLettersEvery3Seconds(array, 0)
这样,您就不必处理循环的同步性质,而是基于调用堆栈和web api(这是超时的正确术语吗?)

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

var array = ['a', 'b', 'c']

function loopLettersEvery3Seconds(arr, index) {
    if (index === arr.length) return loopLettersEvery3Seconds(arr, 0);

    setTimeout(loopLettersEvery3Seconds, 3000, arr, index+1)
}
loopLettersEvery3Seconds(array, 0)

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

var chars=[“a”、“b”、“c”];
函数循环(a,i=0){
log(a[i%a.length]);
设置超时(循环,1000,a,+i);
}

循环(chars)@SeanKwon OP并不想让它阻止它appears@BergiWoops,说得太快了。@Bergi添加了无限循环函数。你能详细解释一下模(余数)运算符在这里是如何工作的吗?另请参见:
(索引+1)%letters.length
此处执行与
(索引+1)
我认为这是一种更优雅的递归方式。如果您好奇,以下是“您的”代码: