2

I have JavaScript code like this:

var buffer=new Array();

function fetchData(min,max){
    var ajaxReq = new XMLHttpRequest(); 
    ajaxReq.onreadystatechange = function(){
    if (ajaxReq.readyState === 4) {
        if (ajaxReq.status === 200) {
            buffer= ajaxReq.responseText;
            console.log(buffer)//this logs an array to console
        } else {
            console.log("Error", ajaxReq.statusText);
        }
    }
    };
    ajaxReq.open('GET', "server/controller.php?min="+min+"&max="+max, true); 
    ajaxReq.send();
}

fetchData(1,100);
console.log(buffer);//this log an empty array

two logs with different result, what am I doing wrong? thanks for pointers.

1
  • The buffer variable in the fetchData function is conditional set. Are you sure ajaxReq.status and ajaxReq.readyState are equaling what you want? Commented Dec 6, 2011 at 21:28

6 Answers 6

8

Ajax is asynchronous. That means that console.log(buffer) at the end is executed before the response from the Ajax request.

You should change your method to this:

function fetchData(min,max,callback){
  var ajaxReq = new XMLHttpRequest(); 
  ajaxReq.onreadystatechange = function(){
    if (ajaxReq.readyState === 4) {
      if (ajaxReq.status === 200) {
        buffer= ajaxReq.responseText;
        callback();
        //console.log(buffer)//this logs an array to console
      } else {
        console.log("Error", ajaxReq.statusText);
      }
     }
  };
  ajaxReq.open('GET', "server/controller.php?min="+min+"&max="+max, true); 
  ajaxReq.send();
}

fetchData(1,100,function(){
    console.log("My Ajax request has successfully returned.");
    console.log(buffer);
});
Sign up to request clarification or add additional context in comments.

1 Comment

Yes, but then your user has to wait for the Ajax response, thus locking up your page. Even if the response seems quick now, there'll inevitably be times where it won't be. In short, don't make your Ajax requests synchronous.
3

You are trying to log() the buffer before the AJAX request in executed. To solve this, your fetchData function needs to handle a callback function.

var buffer=new Array();

function fetchData(min,max, callback){
    var ajaxReq = new XMLHttpRequest(); 
    ajaxReq.onreadystatechange = function(){
    if (ajaxReq.readyState === 4) {
        if (ajaxReq.status === 200) {
            buffer= ajaxReq.responseText;
            console.log(buffer)//this logs an array to console
            if(typeof callback == 'function'){
                callback.call(this);
            }
        } else {
            console.log("Error", ajaxReq.statusText);
        }
    }
    };
    ajaxReq.open('GET', "server/controller.php?min="+min+"&max="+max, true); 
    ajaxReq.send();
}

fetchData(1,100, function(){
    console.log(buffer);
});

This is the most basic implementation, and will work only if the AJAX response is successful.

Comments

2

This is asynchronous. So your flow goes like this:

  1. call fetchData()
  2. ajax request is sent, registering an onreadystatechange callback
  3. fetchData() completes and returns
  4. buffer is logged out, which doesn't yet contain anything.
  5. Sometime later, the ajax request completes and triggers the callback
  6. The callback puts things in the array.
  7. buffer get's logged out from the callback, and you see it now has items in it.

So you are only starting the asynchronous request once you hit that first console.log. But it actually finishes long afterward.

Comments

1

A couple of issues here. When the ajax call completes the 2nd console.log has already executed before the variable was set.

Also,You're not using the buffer varaible as an Array.

3 Comments

what do you mean not using buffer as an array, how can I use it as an array, thanks for help.
buffer.push(ajaxReq.responseText); will push the response text to the end of the array
the ajaxReq.responseText is a multi-dimentional array, how I can add all its child arrays to the buffer?
0

Seems right to me. buffer is empty to start and it doesn't get set until AFTER the asynchronous call is made, so even though you're fetchingData before the second console.log, you're not receiving it until after it shows an empty buffer.

Comments

0

MDN: https://developer.mozilla.org/en/XMLHttpRequest

void   open(in AUTF8String method, in AUTF8String url, in boolean async, in AString user, in AString password);

The third argument is used to tell the browser whether the request should be made asynchronous or not. You set it to true, thus it will be async. Async basically means that the request is sent and meanwhile other code is executed. So, it starts the request, and while waiting for a response, it logs the buffer: before the request has finished. If you want to log the contents, do it in the onreadystatechange event or set the third argument (async) to false.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.