24

I have developed some websites and I always stumble a the same point: multiple ajax calls. I have a main page where all the content is loaded asynchronously. When the page is loaded, there are four INDEPENDENT calls that "draw" the page by areas (top, left, right and bottom) and while it is loaded I show to the user the typical ajax spins. So, when a request is received by the browser I execute the callback and the different areas are drawing at different time. The fact is that the answer for the server sometimes are mixed up, I mean, the answer of top is drawn in the left or vice-versa.

I've tried some solutions like creating a timestamp in each request to indicate to the browser and server that each request is different.

Also I've tried to configure some parameters of cache in the server, in case.

The only way in which works has been including the request2 in the callback of the one, etc.

Anyone knows the proper way to do it or ever has beaten this issue?? I don't want to do chained request.

Thanks

Here is an example of what I mean:

$(document).ready(function() {

$.get('/activity',Common.genSafeId(),function(data){$('#stream').html(data);$("#load_activity").addClass("empty");});
$.get('/messages',Common.genSafeId(),function(data){$('#message').html(data);$("#load_messages").addClass("empty");});
$.get('/deals',Common.genSafeId(),function(data){$('#new_deals_container').html(data);$("#load_deal").addClass("empty");});
$.get('/tasks',Common.genSafeId(),function(data){$('#task_frames').html(data);$("#load_task").addClass("empty");});});

And the html is a simple jsp with four container each one with a different id.

Rahul Desai
  • 15,242
  • 19
  • 83
  • 138
krazy_joss
  • 351
  • 1
  • 2
  • 7
  • 3
    What do you mean, the answer is drawn in the wrong place? Properly constructed, the Ajax call will update a very specific part of the HTML that is in a very specific place in the layout. Post some simple code that demonstrates the issue. – Eric J. Apr 14 '12 at 01:12
  • Are you adding the content to your page with something like $('#container').append()? – jimw Apr 14 '12 at 01:18
  • Yes, I updated the post. The content is added to the DOM, but sometimes the request draws the content in an inappropriate id. I know is weird, for that reason I usually do the chain request. Thanks for your both answer. – krazy_joss Apr 14 '12 at 01:50

2 Answers2

41

CLOSURES

Closures are a little mind-blowing at first. They are a feature of javaScript and several other modern computing languages.

A closure is formed by an executed instance of a function that has an inner function (typically an anonymous event handler or named method) that needs access to one or more outer variables (ie. variables that are within the outer function but outside the inner function). The mind-blowing thing is that the inner function retains access to the outer variables even though the outer function has completed and returned at the time that the inner function executes!

Moreover, variables trapped by a closure are accessible only to inner functions and not to the further-out environment that brought the closure into being. This feature allows us, for example, to create class-like structures with private as well as public members even in the absence of language keywords "Public" and "Private".

Closures are made possible by inner functions' use of outer variables suppressing javaScript's "garbage collection" which would otherwise destroy the outer function's environment at some indeterminate point after completion.

The importance of closures to good, tidy javaScript programming cannot be overstressed.

In the code below the function getData() forms, at each call, a closure trapping id1 and id2 (and url), which remain available to the anonymous ajax response handler ($.get's third argument).

$(document).ready(function() {

    function getData(url, id1, id2) {
        $.get(url, Common.genSafeId(), function(data) {
            $(id1).html(data);
            $(id2).addClass("empty");
        });
    }

    getData('/activity', '#stream', '#load_activity');
    getData('/messages', '#message', '#load_messages');
    getData('/deals', '#new_deals_container', '#load_deal');
    getData('/tasks', '#task_frames', '#load_task');

});

Thus, rather than writing four separate handlers, we exploit the language's ability to form closures and call the same function, getData(), four times. At each call, getData() forms a new closure which allows $.get's response handler (which is called asynchronously when the server responds) to address its DOM elements.

Beetroot-Beetroot
  • 18,022
  • 3
  • 37
  • 44
  • 3
    I learned a lot from this answer, but took me a while to figure out what was wrong with the original code in the question. Is it because the variable "data" is in fact the same object/instance to each call, so gets reused by the inner functions (closures) as well? I guess I half expected the JavaScript run-time would know to create 4 seperate objects here, since they are used in that (somewhat odd) scope, and never before or outside of that. Sure glad I don't have to deal with that level of murkyness in most other languages I work with. – eselk Feb 01 '13 at 23:49
  • @eselk, looking at this again 9 months later, I'm not sure how/why the code in the question could have gotten things mixed up. I think it must have been added after I started to answer the question, and I wonder if it's the OP's own solution, not the code that gave the symptoms described. What's certain is that four independent functions, one per `$.get()`, are unnecessary. My `getData()` function simplifies matters. Once you have your mind round closures, they are quite simple - and certainly much simpler in practice than a formal definition would have you believe. – Beetroot-Beetroot Feb 02 '13 at 02:18
  • @Beetroot-Beetroot I need to make 12 ajax calls simultaneously on the page load..It seems like one response is being copied into another for some. Is this due to browser limitations of number of concurrent calls? – techie_28 Aug 12 '16 at 10:49
-5

Make sure you have different callbacks for each ajax call, it sounds like you are trying to use the same function for all four, thus when they are called out of order (because they take different amounts of time server-side), they are rendering in the wrong place. If you insist on using the same function for all your callbacks, then you have to put something in the payload so that the callback knows where to render to.

Robert Louis Murphy
  • 1,558
  • 1
  • 16
  • 29