How to do sequential asynchronous ajax requests with given number of streams

前端 未结 3 1318
忘掉有多难
忘掉有多难 2020-12-31 21:21

I need to make sequential asynchronous ajax requests with limited streams. As of now I am allowed to occupy only one stream on web server so I can only do one ajax request a

相关标签:
3条回答
  • 2020-12-31 21:25

    As long as your callbacks are all synchronous this should work for you, if not put you on the right track

    var initiateChain = function () {
    
        var args = arguments,
            index = 0,
            length = args.length,
            process = function ( index ) {
    
                if ( index < length ) {
                    $.ajax({
                        url: '/example.php',
                        complete: function () {
                            // Callbacks get run here
                            args[ index ];
                            process( ++index );
                        }
    
                    });
                }
    
    
            };
    
        if ( length ) {
            process( 0 );
        }
    
    };
    
    initiateChain( getGadgets, getDeals, getDeals );
    
    0 讨论(0)
  • 2020-12-31 21:44

    Thanks @James, I got clue from what you edited for length. As such the calls are async ajax requests. So the idea is in creating M number of async calls upfront. Then they will continue those many as and when each one is complete.

    I did experiment with nodejs and following initiateChain works as intended

    var calls = [];
    
    function initiateChain() {
        var i = 0;
        var maxSteams = 2;
        var tasks = arguments;
        var callback = function () {
          i += 1;
          if (i < tasks.length) {
            tasks[i](callback); //block should call callback when done otherwise loop stops
          }
        }
        if (tasks.length) {
          i = ((tasks.length > maxSteams) ? maxSteams : tasks.length) - 1;
          for (var j = 0; j < maxSteams; j+=1) {
            if (j < tasks.length) {
              tasks[j](callback); //initiate first set
            } else {
              break;
            }
          }
        }
    }
    
    //test methods
    for(var k = 0; k < 8; k+=1 ) {
      calls[k] = (function (message, index) {
        return function (callback) {
          var ts = new Date().getTime();
          console.log(message + " started - " + ts);
          setTimeout(function() {
            ts = new Date().getTime();
            console.log(message + " completed - " + ts);
            callback();
          }, index * 1000);
        };
      })("call" + (k+1), (k+1))
    }
    
    initiateChain(calls[0], calls[1], calls[2], calls[3], 
        calls[4], calls[5], calls[6], calls[7]);
    

    In my experiment I got following results

    call1 started - 1360580377905
    call2 started - 1360580377926
    
    call1 completed - 1360580378937
    call3 started - 1360580378937
    
    call2 completed - 1360580379937
    call4 started - 1360580379937
    
    call3 completed - 1360580381945
    call5 started - 1360580381945
    
    call4 completed - 1360580383946
    call6 started - 1360580383946
    
    call5 completed - 1360580386959
    call7 started - 1360580386959
    
    call6 completed - 1360580389950
    call8 started - 1360580389950
    
    call7 completed - 1360580393972
    
    call8 completed - 1360580397959
    
    0 讨论(0)
  • If you're using jQuery then you can use its .queue method to queue up your ajax calls and then execute them in sequence. To run multiple sequences, you can wrap the initial dequeue in a loop.

    function add_api_call_to_queue(qname, api_url) {
        $(document).queue(qname, function() {
            $.ajax({
                type     : 'GET',
                async    : true,
                url      : api_url,
                dataType : 'json',
                success  : function(data, textStatus, jqXHR) {
                    // activate the next ajax call when this one finishes
                    $(document).dequeue(qname);
                }
            });
        });
    }
    
    $(document).ready(function() {
    
        var queue_name       = 'a_queue';
        var concurrent_calls = 2;
    
        // add first AJAX call to queue
        add_api_call_to_queue(queue_name, '/example/api/books');
    
        // add second AJAX call to queue
        add_api_call_to_queue(queue_name, '/example/api/dvds');
    
        // add third AJAX call to queue
        add_api_call_to_queue(queue_name, '/example/api/shoes');
    
        // start the AJAX queue
        for (i=0;i<concurrent_calls;i++) {
            $(document).dequeue(queue_name);
        }
    
    })
    
    0 讨论(0)
提交回复
热议问题