Make jQuery ajax calls in order

前端 未结 2 774
[愿得一人]
[愿得一人] 2020-12-15 14:39

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:

相关标签:
2条回答
  • 2020-12-15 14:53

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

    0 讨论(0)
  • 2020-12-15 14:54

    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.

    0 讨论(0)
提交回复
热议问题