Я ожидал, что код ниже предупредит "0" и "1", но он предупреждает "2" дважды. Я не понимаю причины. Не знайте, является ли это проблема jQuery. Кроме того, помогите мне отредактировать заголовок и теги этого сообщения, если они неточны.
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript">
$(function() {
for (var i=0; i<2; i++) {
$.get('http://www.google.com/', function() {
alert(i);
});
}
});
</script>
</head>
<body>
</body>
</html>
Вы разделяете единственную переменную i
между всеми обратными вызовами.
Поскольку замыкания в Javascript захватывают переменные по ссылке, обратные вызовы всегда будут использовать текущее значение i
. Поэтому, когда jQuery вызовет обратные вызовы после выполнения цикла, i
всегда будет 2
.
Вам нужно ссылаться на i
как на параметр отдельной функции.
Например:
function sendRequest(i) {
$.get('http://www.google.com/', function() {
alert(i);
});
}
for (var i = 0; i < 2; i++) {
sendRequest(i);
}
Таким образом, каждый обратный вызов будет иметь отдельное закрытие с отдельным параметром i
.
Здесь происходит то, что ваш запрос AJAX $. Get
завершается после завершения цикла. Из-за этого i
в конечном итоге становится последней переменной, которая устанавливается после завершения итераций, равной 2. Это просто странная ошибка JavaScript, не имеющая ничего общего с jQuery.
Единственное, что вы можете сделать, - это поставить эти вызовы в очередь асинхронно, чтобы итерация останавливалась до завершения текущего запроса AJAX. Если вы не хотите этого делать, вы можете зафиксировать переменную i
в закрытии функции
на каждой итерации.
Примерно так:
for ( var i = 0; i < 2; i++ )
(function(iter){
$.get('http://www.google.com/', function(){
alert( iter );
});
})(i); // Capture i
Похоже, что вы создали закрытие внутри своего цикла. В Справочнике разработчиков Mozilla есть хороший раздел об этом.
Альтернатива ответу Слакс
$(function() {
for (var i=0; i<2; i++) {
$.get('http://www.google.com/', function(i) {
return function() { alert(i); }
}(i));
}
});