У меня возникла проблема с асинхронным выполнением кода в JavaScript
Вот пример кода, который показывает суть проблемы:
function display(value) {
console.log(value);
}
А в другом месте в коде я использую следующее:
var value = 10;
var index = 0;
while (value > 0) {
setTimeout(function() {display(value);}, 500 * index);
value--;
index++;
}
Я ожидал получить вывод 10 9 8 7 6 5 4 3 2 1, но вместо этого вижу 0 0 0 0 0 0 0 0 0 0.
Не понимаю, почему значение переменной изменилось до того, как выполнится функция setTimeout? Как мне исправить этот момент, чтобы получить нужный результат?
Можно также использовать bind — довольно элегантное решение. setTimeout(display.bind(null, value), 500 * index) работает отлично. bind создает новую функцию с фиксированным значением, так что каждый колбэк запоминает свое число. Почему ты используешь while вместо for?
Да, это классическая проблема с областью видимости. С var все колбэки ссылаются на одну переменную, и к моменту выполнения она уже равна 0. Проще всего заменить var на let — тогда каждая итерация получит свое значение. Или можно обернуть в IIFE:
for (var i = 10; i > 0; i--) {
(function(val) {
setTimeout(() => display(val), 500 * (10 - val));
})(i);
}
Это решит проблему.