0

Немного непонятно с данным кодом - почему внутри квадратов выводится цифра 5, а не последовательные 0..4?

Есть версия:
- цикл прогоняется намного быстрее, и пока выполнится первый setTimeout, счетчик уже достиг максимального значения.

$(function() {
  for (var i = 0; i < 5; i++) {
    setTimeout(function() {
      $('.rows').append('<div>' + i + '</div>');
    }, 800 * i);
    $('.res').text($('.res').text() + " " + i);
  }
});
.rows > div {
  width: 50px;
  height: 50px;
  background-color: #3c3;
  margin: 5px;
  float: left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="rows">
  <div></div>
</div>
<div class="res"></div>
Jean-Claude
  • 5,841
  • 2
  • 20
  • 45

1 Answers1

3

Так как вызов setTimeout Не останавливает выполнения, а просто планирует вызов функции цикл выполняется сразу весь.
Таким образом на последней итерации:

значение i = 4.
вызывается i++, значение уже 5
проверка условий цикла i < 5
выход из цикла.

Таким образом после окончания цикла значение переменной равно 5.

Следом начинают выполняться функции запланированные с помощью setTimeout

function() {
  $('.rows').append('<div>' + i + '</div>');
}

Так как значение i - 5, то и выводится 5.

цикл прогоняется намного быстрее, и пока выполнится первый setTimeout

Неверная догадка. Так как яваскрипт выполняется в одном потоке, выполнение функции не может прерываться. То есть, независимо от значения интервала указанного в таймауте сначала выполнится весь цикл и оставшаяся часть функции и лишь затем, если в очереди ничего нет, будет выполнена отложенная функция.

Grundy
  • 81,538
  • Да-да, с последней итерацией сразу же после задания вопроса разобрался. – Jean-Claude Mar 25 '16 at 10:54
  • А если for() внутри for()? Первый прерывается или нет пока выполнится вложенный for()? – Jean-Claude Mar 25 '16 at 10:58
  • @Jean-Claude, выполнение строго последовательно. Обыкновенная однопоточная программа. – Grundy Mar 25 '16 at 11:00
  • @Jean-Claude, кстати, не совсем понял как первый for может прерваться, если вложенный выполняется внутри него – Grundy Mar 25 '16 at 11:01
  • да так, из ответа выбрал слова) а какие еще есть функции, планирующие вызов функций? – Jean-Claude Mar 25 '16 at 11:05
  • @Jean-Claude, setInterval: WindowTimers – Grundy Mar 25 '16 at 11:05