Nilesh
Nilesh

Reputation: 2115

Multiple Ajax post calls - chain them so the next ajax post is called only after the first success

This question is trying to confirm my understanding and how best to solve the situation at hand.

In my application, let say I have five containers and each of these containers has its own data source URL.

Upon loading of the page, all five need to ask the server, retrieve the data and display it.

Currently, as soon as the page is loaded, I fire the jquery ajax.post method for each of the containers in a loop. The loop executes instantly and in Firebug I see all these ajax requests as "processing"

Now my understanding is that javascript is single threaded so all of these ajax requests are still somewhere in the browser's execution queue, right?

What I want is that even though I fired all the 5 ajax post requests in a loop, it should hit the server only one after the other.

For e.g 1st Ajax call success or failure --> Call 2nd ajax post --wait for success or failure and then fire the third ajax post and so on.

I don't want to hit the server with 5 parallel ajax calls so I want to confirm that the ajax.post for all those 5 containers in a loop is not a parallel operation.

If for any reason there is a chance of some browser doing parallel requests then I would like to implement a simple chaining mechanism which I can do it using the call back function of each ajax post.

I looked at the jquery queue function but the calls are q'd for the same object. In my case I need to call same function on different objects in a sequential manner.

If you can tell me what is the best practice, and whether my assumptions and understanding needs corrections.

Thank you

Upvotes: 2

Views: 8599

Answers (2)

Shyju
Shyju

Reputation: 218812

Ajax stands for Asynchronous JavaScript and XML. Yes Asynchronous.

If you want to disable the Asynchronous way, you can set the async property to false;

$.ajax({
        async: false,
        // ...
        success: function(data) {
           //do whatever with your data
        }
    });

EDIT : Here is the examples and its output.

HTML

<div id="div1"></div>   

Case 1 :

I am not setting the asyn property to false. So it will use the default (ie: async=true. The ajax calls will be asynchronous).

<script type="text/javascript">
    $(function () {
        for (var i = 0; i < 3; i++) {               
            $.ajax({
                url: 'ajaxserverpage.aspx',
                cache: false,                   
                success: function (data) {                       
                    $("#div1").append(data);                     
                }
            });
        }
    });    
</script>

I am calling an aspx page in my ajax call. My aspx page will simply return the current datetime value. I am appending that to my div. I have a Thread.Sleep(2000) statement in my aspx page to impose a 2 seconds delay in the response ( to demonstrate the response time difference).

Code behind of ajaxserver.aspx page

 protected void Page_Load(object sender, EventArgs e)
 {
     Thread.Sleep(2000);
     Response.Write("<br/>created at "+DateTime.Now.ToString());
     Response.End();
 }

Lets see how it works.

Here is my outputs.

enter image description here

When i inspect firebug, i could see this. enter image description here

You can see that we have 3 calls to my server page and it all started at the same time.Second one is not waiting for the first one to complete.

Case 2

I am going to set async property value to false.

$(function () {
            for (var i = 0; i < 3; i++) {               
                $.ajax({
                    url: 'ajaxserverpage.aspx',
                    cache: false,
                    async:false,
                    success: function (data) {                       
                        $("#div1").append(data);                     
                    }
                });
            }
        }); 

and the results are

enter image description here

and the firebug result is

enter image description here

You can see that the second request started after the first one is completed and the third one started after the second.

Hope this helps.

Upvotes: 6

jedmao
jedmao

Reputation: 10502

You could also use recursion—something like so...

function chainContent(container) {
    $.ajax({
        url: container.data('url'),
        success: function(html) {
            container.html(html);
            var next = container.next();
            if (next != null) chainContent(next);
        }
    });
}

loadContent($('#container_1'));

And the HTML...

<div id="container_1" data-url="load_1.htm"></div>
<div id="container_2" data-url="load_2.htm"></div>
<div id="container_3" data-url="load_3.htm"></div>

Upvotes: 4

Related Questions