for ( var i=0; i<10; i++ ) {
var url = aUrl[i];
new Ajax.Request(url,
{
method:'get',
onSuccess: function(transport){
alert('call url i='+i);
}
});
}
Du notierst hier 10 Funktionen in der Schleife und greifst in den Funktionen auf die Laufvariable der Schleife zu. Dass das möglich ist, geht überhaupt deshalb, weil die Funktionen Closures darstellen. Die einzelne Funktion wird aber nicht sofort aufgerufen, sondern asynchron - nämlich auf jeden Fall *nach* dem Durchlaufen der Schleife (das ist garantiert, weil JavaScript single-threaded ist).
Die Closure legt keine Kopie der Variable i mit dem gegenwärtigen Wert an, sondern bloß eine Verknüpfung. Wenn sich also der Wert von i ändert, dann greifen all die onSuccess-Funktionen, die du in der Schleife erzeugst, auf diesen geänderten Wert zu.
Es gibt zwei Möglichkeiten, wie du in der Closure an den richtigen i-Wert kommst:
1. eine weitere Closure per namenlosen Funktionsausdruck, der sofort ausgeführt wird, die den aktuellen i-Wert einschließt
for (var i = 0; i < 10; i++) {
(function (i) {
new Ajax.Request("...", {
onSuccess : function (response) {
alert(i);
}
});
})(i);
}
2. Den i-Wert am XMLHttpRequest-Objekt speichern, welches über transport beim Objekt verfügbar ist, das der Ajax.Request-Konstruktor zurückgibt
for (var i = 0; i < 10; i++) {
var request = new Ajax.Request("...", {
onSuccess : function (response) {
alert(response.i);
}
});
request.transport.i = i;
}
Mathias