Понимание асинхронности функции setTimeout() в JavaScript

dall e 2024 08 03 12.45.36 a dynamic illustration showing the concept of javascripts settimeout function in action within a for loop. the image should depict a sequence of nu HTML

Функция setTimeout() является асинхронной, что означает её выполнение начинается только после завершения всех операций в основном потоке JavaScript. Интересно рассмотреть, что произойдёт, если использовать эту функцию внутри цикла for.

for (var i = 0; i < 5; i++) {
setTimeout(() => console.log(i), 0);
}

Какой результат будет выведен на экран?

Для начала, упростим задачу: уберём setTimeout() и оставим только console.log(i) внутри цикла. В таком случае, все операции будут выполняться в основном потоке, и каждое значение i будет выведено на экран по мере выполнения итераций цикла. В результате, на экране появится последовательность чисел от 0 до 4.

Что происходит с setTimeout()?

Когда мы используем setTimeout() внутри цикла, вызов console.log(i) будет происходить после завершения всех операций в стеке. Это означает, что к моменту выполнения setTimeout() все итерации цикла будут завершены и значение переменной i достигнет 5.

Почему на экран выводится одно и то же значение?

Переменная i объявлена с использованием ключевого слова var. Это означает, что она имеет функциональную область видимости (а в данном случае — глобальную), и её значение изменяется с каждой итерацией цикла. Поскольку setTimeout() выполняется после завершения цикла, все пять вызовов console.log(i) увидят одно и то же значение i, равное 5.

Итоговый вывод:

Таким образом, на экран 5 раз будет выведено число 5, каждое на новой строке.

Пример кода для лучшего понимания:

for (var i = 0; i < 5; i++) {
setTimeout(() => console.log(i), 0);
}

Альтернатива с использованием let

Для тех, кто хочет, чтобы каждый вызов console.log(i) выводил текущее значение i на момент итерации, можно использовать ключевое слово let, которое имеет блочную область видимости:

for (let i = 0; i < 5; i++) {
setTimeout(() => console.log(i), 0);
}

В этом случае на экран будут выведены значения от 0 до 4, так как каждая итерация создаёт новую область видимости для переменной i.

Оцените статью