Search code examples
javascriptjqueryajaxjquery-deferred

Chaining and queuing ajax requests using jQuery deferred


I have a clunky ajax queue that uses setTimeout and a global flag:

var InProgress = false;

function SendAjax(TheParameters) {

  if (InProgress) {
     setTimeout(function () { SendAjax(TheParameters) } , 500) 
  }

  InProgress = true;

  $.ajax({
    ...
    data: TheParameters,
    complete: InProgress = false
  });
}

How can I rewrite this using a queuing mechanism so that the requests trigger one after the other in the order they're received?


Solution

  • By using then we can chain each request sequentially as they come in.

    var previousPromise;
    
    // This actually sends the request
    function actualSender(params) {
      return $.ajax(...);
    }
    
    // This will make sure that the next request will be fired
    // when the previous one finishes.
    function SendAjax(TheParameters) {
      if (previousPromise) {
        // Even if the previous request has finished, this will work.
        previousPromise = previousPromise.then(function () {
          return actualSender(TheParameters);
        });
        return previousPromise;
      }
    
      // first time
      previousPromise = actualSender(TheParameters);
      return previousPromise;
    }
    

    I didn't test this but the idea should work