首页 > 解决方案 > 在`for`循环中嵌套`setTimeout`s

问题描述

我在一个阵列中有多个灯泡。我正在尝试一个一个地打开和关闭灯泡。每个灯泡应打开 1 秒钟(一个接一个),然后所有灯泡应关闭 2 秒钟。

但是在下面的代码中,输出不是预期的顺序。似乎内部setTimeout()不遵循外部延迟时间。

var array = [1, 2, 3, 4, 5, 6];
for (let i = 0; i < array.length; i++) {
  setTimeout(function() {
    console.log(i + " is on");
    setTimeout(function() {
      console.log(i + " is off");
    }, i * 1000);
  }, i * 3000);
}

我不必setTimeout()在这里使用(如果有更好的选择)。

任何想法将不胜感激。

标签: javascriptsettimeout

解决方案


您的嵌套超时 ( off) 将仅在其“父”超时 ( on) 触发时设置。

这样,您的off-timeouts 时间将添加on-timeouts 时间 ( i * 3000 + i * 1000) 中:

0*3000 + 0*1000 =     0
1*3000 + 1*1000 =  4000
2*3000 + 2*1000 =  8000
3*3000 + 3*1000 = 12000
4*3000 + 4*1000 = 16000
5*3000 + 5*1000 = 20000

如果将这些值与on-timeouts 进行比较,您会得到:

ON  0     0
OFF 0     0
ON  1  3000
OFF 1  4000
ON  2  6000
OFF 2  8000
ON  3  9000
OFF 3 12000
ON  4 12000
ON  5 15000
OFF 4 16000
OFF 5 20000

因此,没有必要在-timeoutsi *的情况下。off

var array = [1, 2, 3, 4, 5, 6];
for (let i = 0; i < array.length; i++) {
  setTimeout(function() {
    console.log(i + " is on");
    setTimeout(function() {
      console.log(i + " is off");
    }, 1000);
  }, i * 3000);
}

此外,如果可能,最好避免嵌套超时,因为它们会增加延迟。相反,在添加时间的情况下创建它们。

像这样:

var array = [1, 2, 3, 4, 5, 6];
for (let i = 0; i < array.length; i++) {
  setTimeout(function() {
    console.log(i + " is on");
  }, i * 3000);
  setTimeout(function() {
    console.log(i + " is off");
  }, i * 3000 + 1000);
}


推荐阅读