Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make jQuery ajax calls in order

Tags:

jquery

ajax

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:

  • some requests maybe jsonp (the most relevant)
  • I have other ajax requests that may work meanwhile..
  • The browser got blocked

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.

like image 250
ilyes kooli Avatar asked Feb 20 '23 05:02

ilyes kooli


2 Answers

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.

like image 136
ilyes kooli Avatar answered Feb 22 '23 19:02

ilyes kooli


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.).

like image 29
WiredPrairie Avatar answered Feb 22 '23 19:02

WiredPrairie