miki725
miki725

Reputation: 27861

AJAX (XMLHTTPRequest) time delay

I am new to AJAX and have this issue.

I am creating a photogallery page and on it I created a Javascript class which manager the whole thing. Here is a method from the class which calls XMLHTTPRequest object which was initialized successfully earlier:

this.AJAX_update = function(id) {
    //initialize AJAX - this is done successfully
    this.AJAX_initialize();
    var url = "ScriptLibrary/gallery_update.php?img=" + id;
    //this.ajax_request is an internal variable which is
    //initialized in this.AJAX_initialize() and is
    //XMLHTTPRequest type
    this.ajax_request.open("GET", url, true);
    this.ajax_request.onreadystatechange = processAJAX;
    this.ajax_request.send(null);
}

I could not figure out how to call class' internal method in onreadystatechange, so I created a function outside of the class which calls a method inside the class provided that the instance of the class has been created on the page which it is. The instance of the class on the page is the variable 'gallery'. Here is the function:

function processAJAX() {
    gallery.AJAX_process();
}

Here is the code of the AJAX_process() function:

this.AJAX_process = function() {
    if (this.ajax_request.readyState == 4) {
        if (this.ajax_request.status == 200) {
            //get the response
            var response = this.ajax_request.responseXML;

            //Here I set the internal variables according to the value
            //returned from the server
            //...........
            //...........
            //...........

            //change image on the page
            var self = this;
            setTimeout(function() {
                self.swap_dissolve();
            }, 50);

        }
    }
}

So, here is my question:

Initially I tried to call the internal function directly by just doing this.swap_dissolve() however it does not work. Basically the AJAX_process() method changes values of certain class' internal variables according to the response from the server, and those values are used in the swap_dissolve() to actually change the image on the page. What would happen is that swap_dissolve() would not change the image correctly because it was seeing null or not updated values of the variables AJAX_process() updated. When I added the time delay, the problem disappeared. I don't understand why that is happening. I do check that the readyState == 4, so the response from the server has been completely returned, therefore whatever values the function sets, are final and can be used right away, so why can't I use those values right away and have to wait?

Any suggestions or faults in my code to resolve this issue would be highly appreciated.

If you have any question to me, please post response to this question.

Thank you.

Upvotes: 0

Views: 2911

Answers (1)

user166390
user166390

Reputation:

You want to use a 'closure' (e.g. pass a function-object to setTimeout).

Imagine this (heck, substitute it in your code to see):

// when response = 200
var someValue = "blahblah" // whatever you read in
setTimeout(function () {
  alert(someValue)
}, 1000)

The alert should display "blablah" (or whatever you assigned to it). The value is available to the anonymous function object because a closure-binding has been created (the function can access the variables of the enclosing function scope(s).

Here is a reference: http://jibbering.com/faq/notes/closures/ and more of a soft intro: http://blog.morrisjohns.com/javascript_closures_for_dummies.html

Happy coding.

Edit/P.S. You can also write the AJAX handler like (it's just a closure to force the correct 'this' context -- some frameworks offer convenience functions for this):

var self = this
this.ajax_request.onreadystatechange = function () {
   self.process_AJAX()
}

You can even use a double-binding, but... happy coding, again :-)

Upvotes: 1

Related Questions