Задать вопрос
splincodewd
@splincodewd
Developer

Как понять такое поведение участка кода на js?

Мда, после такого считаю себя нубом.

1) Что выведется в консоль? Как добиться правильного вывода в консоль, не убирая setTimeout?
for (var i = 0; i < 10; i++) {
  setTimeout(function () {
    console.log(i); // ?
  }, 0);
}


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

58eb04456b544936925189c9509e0f2d.png

Как объясняется такое поведение?
  • Вопрос задан
  • 449 просмотров
Подписаться 1 Оценить 1 комментарий
Решение пользователя Сергей К ответам на вопрос (5)
@void01
цикл пробегается раньше чем отрабатывает timeout
/* написаное ниже - ошибочно */
JS однопоточен, поэтому setTimeout фактически выбрасывает код в конец текущего обработчика, когда i == 10
/* написаное выше - ошибочно */

можно прибегнуть к ES6 и использовать оператор let
for (let i = 0; i < 10; i++) {
  setTimeout(function () {
    console.log(i); // ?
  }, 0);
}


таким образом мы сократили область видимости переменной i до блока внутри цикла
а в случае с var переменная была общая и setTimeout выводил только ее конечное значение

UPD: дока для ознакомления тут https://learn.javascript.ru/let-const

UPD2: По поводу однопоточности я ошибся (в том что это причина).
Исправляюсь )) как оказалось. setTimeout(func,0) и setTimeout(func,4) выполнятся одновременно.
По крайней мере в хроме. минимальный порог значения таймаута в разных браузерах может отличаться, но он больше 0мс. В хром это 4мс. обусловлено это тем, что многие используют setTimeout для асинхронности и страница где несколько setTimeout(func,0) сильно нагрузит процессор. По крайней мере базовой причиной появляения минимальной задержки называют это.
Ответ написан