2

This is driving me nuts. I can't work it out stepping through with Firebug either. Can someone please explain what is going on here?

Basically I have an incoming text file where each line contains a pipe-delimited record. I'm splitting these into an array of array of string for later use in an autocomplete textbox. The code is as follows:

<script type="text/javascript">
$(function () {

    var rawData = new Array();
    $.get("/sample.txt",
        function (data) {
            var raw = data.split('\n');
            for (var i = 0; i < raw.length; i++) {
                rawData.push(raw[i].split('|'));
            };
            alert(rawData); // 1st sanity check
        }
    );
    alert(rawData); // 2nd sanity check
    alert(rawData); // 3rd sanity check

For some reason the first sanity check works fine - it displays all the data as I'd expect. The second one displays that rawData is empty... but the 3rd one shows all of the data again. Removing the 1st sanity check doesn't affect the 2nd and 3rd.

How is this possible? Why is this so? This is driving me crazy.

nathanchere
  • 8,008
  • 15
  • 65
  • 86

1 Answers1

5

You are forgetting that the get() function is an asynchronous function. The callback you define inside will only get called once the file is loaded. In essence, the JavaScript interpreter puts it in a queue ready for when the action completes, and then allows the rest of the code to execute.

So, your alert in the callback will reflect the fact that the file was loaded. The alerts outside will execute well before that file is loaded. Of course, the longer you personally wait to dismiss the second alert, the better the change that the third alert will execute when all the data is loaded.

jmbucknall
  • 2,061
  • 13
  • 14
  • The bit that confuses me is that 1st alert will fire first (in the presumably async function), then the second alert fires with an empty value, then the third with a value again. To me it makes no sense, asynchronous or otherwise. – nathanchere Jun 09 '11 at 03:05
  • Basically, by the time the first alert is called, the data has definitely been loaded... and I can't see how it's possible for the second alert to still have no data, even if it's being queued with the initially empty rawData value, because it would surely appear before the $.get - triggered alert if that was the case? – nathanchere Jun 09 '11 at 03:07
  • It's not a completely conclusive answer but it's enough for me to get over this particular road block - putting the rawData-dependant code inside the $.get function does the trick. Thanks! – nathanchere Jun 09 '11 at 03:18
  • Replace the alerts with something like alert("1"), alert("2"), etc to see which order they're fired in. Or use Firebug and use console.log(). – jmbucknall Jun 09 '11 at 03:57
  • 1
    Then the file you are retrieving is in the browser cache, has not expired, and is loaded immediately. The success callback is called synchronously. My point is: this behavior cannot be relied on, you must assume that the callback is called asynchronously. – jmbucknall Jun 09 '11 at 15:49