ilyes kooli
ilyes kooli

Reputation: 12053

Make jQuery ajax calls in order

I want to make a stack of Ajax calls in this way: call(n) starts after call(n-1) finished...

I cannot use async:false for many reasons:

I cannot chain my requests this way:

$.post('server.php', {param:'param1'}, function(data){
        //process data
    $.post('server.php', {param:'param2'}, function(data){
        //process data
    });
});

Because the number and params of the requests are dynamically created from user input.

A small example that illustrates my problem.

You will see that the server response order is random, what I want to achieve is to have it in order

Response to arg1
Response to arg2
Response to arg3
Response to arg4
Response to arg5
Response to arg6

Any help would be very appreciated, thanks.

Upvotes: 4

Views: 7665

Answers (2)

ilyes kooli
ilyes kooli

Reputation: 12053

Ok, jQuery Ajax returns a Deferred Object, this can help you achieve this.

Here is how to do it:

var args = ['arg1','arg2','arg3','arg4','arg5','arg6'];

deferredPost(0, 5);

function deferredPost(index, max){    
    var delay = Math.random()*3;
    if (index<max){
        return $.post('/echo/html/', {html:('Response to '+args[index]), delay:delay}, 
        function(data){
            $('#response').append(data+'<br>');
        }).then(function(){
            deferredPost(index+1, max);
        });
    } else {
        return $.post('/echo/html/', {html:('Response to '+args[index]), delay:delay}, 
        function(data){
            $('#response').append(data+'<br>');
        });
    }
}

DEMO

Here I used then function.

I also recommend to read a little bit more about deferred objects, they can solve a couple of common problems.

Upvotes: 7

WiredPrairie
WiredPrairie

Reputation: 59793

This is a job for a queue.

var queue = ['arg1','arg2','arg3','arg4','arg5','arg6'];

function runQueueInOrder() {
    if (queue.length === 0) { return; }
    var arg = queue.pop();
    var delay = Math.random()*3;
    $.post('/echo/html/', {html:('Response to '+ arg), delay:delay}, 
        function(data){
            $('#response').append(data+'<br>');        
    }).then(function() {
        runQueueInOrder();
    });        
}

runQueueInOrder();

You don't need to use jQuery's then for this to work if you've encapsulated the processing of the queue in a function. It's handy though. The code is destructive as it removes elements from the original array (but as they are processed, it's usually OK).

The method runQueueInOrder is called to initiate processing.

When there is no more work to be done, the function simply exits. (I've written a version that polls on a timer before, but that's not needed here).

The function grabs the next work arg, calls your post call syntax, and when done uses jQuery's deferred then callback to call the function again (to process the queue further if needed).

(I looked at the other answer and found it confusing to follow, so I took a simpler approach. Using my simple version, you can add new items as new work is discovered--or remove them.).

Upvotes: 1

Related Questions