как передать значение приращения для обратного вызова

58
7

Я повторяю массив, и для каждого элемента делаю что-то, что вызывает обратный вызов. Моя проблема заключается в том, что в обратном вызове мне нужно знать, к какому проходу его итерации.

Упрощенный, мой код выглядит так...

for (var i=0; i<3; i++ {
setTimeout(function () {
console.log(i);
},1000);
}

И я хочу увидеть

0
1
2

То, что я получаю, это

3
3
3

Я понимаю, почему я получаю 3, но не могу понять, как получить 0,1,2

NB. Это упрощенная версия моей проблемы. В myapp я фактически вызываю операцию хранения, поэтому я не могу просто предоставить "i" в качестве аргумента функции обратного вызова.

спросил(а) 2013-10-10T19:24:00+04:00 7 лет назад
1
Решение
99

Вам нужно зафиксировать значение во время итерации, так как JS имеет область функций, поэтому он тот же i что вы ссылаетесь (и вы этого не хотите, поэтому вам нужно создать закрытие.

for (var i = 0; i < 3; i++) {
(function (a) {
setTimeout(function () {
console.log(a);
}, 1000);
})(i);
}

ответил(а) 2013-10-10T19:26:00+04:00 7 лет назад
59

Почему вы получаете i как 3, потому что settimeout является асинхронным, и обе ваши функции forloop и set timeout используют одну i ту же переменную i. Это означает, что цикл for полностью запускается до вызова обратных вызовов, где я мог бы перейти к 3 после всех ваших итераций. Таким образом, ваша работа заключается в создании локальной области для переменной или в других словах, создающей закрытие.

for (var i=0; i<3; i++) {
(function(iter){ //Now with this you are creating a local closure for the variable iter and each setTimeout instance will no longer share the variable 'i' instead it will use the variable created in its own scope defined by the anonymous function.
setTimeout(function () {
console.log(iter);
},1000);
})(i)
}

ответил(а) 2013-10-10T19:28:00+04:00 7 лет назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема