Вложенный цикл `setTimeout`s в` for` - PullRequest
2 голосов
/ 15 апреля 2020

У меня есть несколько лампочек в одном массиве. Я пытаюсь включать и выключать лампочки одну за другой. Каждую лампочку следует включить на 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() здесь (если есть лучшая альтернатива).

Любая идея будет оценена.

1 Ответ

2 голосов
/ 15 апреля 2020

Ваш вложенный тайм-аут (off) будет установлен только тогда, когда его «родительский» тайм-аут (on) сработает.

Таким образом, ваши off тайм-ауты добавляются добавлены Время ожидания от до on (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, вы получите:

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

Следовательно, i * -time-time не требует *1017*.

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