-1

I am pretty new to this site. I have a question when working on a XMLHttpRequest which is replicated in a for loop as following:

I don't understand the difference between the following two blocks of code:

function changeForm(i) {
    if (selection[i-1] != 0) {
        xmlhttp = new XMLHttpRequest();
        xmlhttp.onreadystatechange = function() {
            if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                document.getElementById("box"+i).innerHTML = xmlhttp.responseText;
            }
        };
        xmlhttp.open("POST", "fetchLineChoice_addData.php", true);
        xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
        xmlhttp.send("index="+i+"&lc="+selection[i-1]);
    } else {
        document.getElementById("box"+i).innerHTML = "";
    }
}

for (var i = 1 ; i < 4 ; i++) {
    changeForm(i);
}

AND

for (var i = 1 ; i < 4 ; i++) {
    if (selection[i-1] != 0) {
        xmlhttp = new XMLHttpRequest();
        xmlhttp.onreadystatechange = function() {
        if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                document.getElementById("box"+i).innerHTML = xmlhttp.responseText;
            }
        };
        xmlhttp.open("POST", "fetchLineChoice_addData.php", true);
        xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
        xmlhttp.send("index="+i+"&lc="+selection[i-1]);
    } else {
        document.getElementById("box"+i).innerHTML = "";
    }
}

I don't really know why the first one works but the second one does not. I have tried to search on the net about closures and came up with these two:

Calling a XMLHttpRequest continuously

JavaScript closure inside loops – simple practical example

From the second question, it was mentioned that the function is bound to a variable i outside the function. I would like to know for the second block of code (that does not work), I would like to know why the content in the for loop is not fully executed before the value of i increases again? What is the flow when the two blocks of code are being executed?

Thank you very much!

Community
  • 1
  • 1
Nguyen H Chan
  • 61
  • 2
  • 10
  • the second question you linked to explains this problem in detail. what exactly do you not understand from it's explanation? *"Well, the problem is that the variable i, within each of your anonymous functions, is bound to the same variable outside of the function."* all of the callbacks, will use the same `i` if you don't create a separate scope for each iteration so that each has its own `i`. – Kevin B Jun 28 '16 at 18:44
  • Actually I am quite confused with the concept of the scope of variables in the functions that are being iterated. So is it that the block of code inside the loop will be executed but the value of i will change independently, without completing the whole process? – Nguyen H Chan Jun 29 '16 at 07:04
  • the callback is asynchronous, it happens later. by the time it does happen, the loop is finished and `i` is at the final value. – Kevin B Jun 29 '16 at 15:05

1 Answers1

1

The first one works because the value of "i" does not get written over. It is "closed over" and remains the same throughout the execution.

In the second example, the iteration spawns XMLHttpRequest, but the global value of "i" changes. By the time the request is complete, it is no longer pointing to the value of "i" you are expecting.

Phil
  • 60
  • 6