I recently encountered a similar issue and managed to find a resolution, so I wanted to take the opportunity to share my solution here on SO.
Here is the approach I took:
//Custom Global Variables:
var ajaxQue = []; //array storing immediate queue of ajax object requests to be sent
var ajaxCache = {}; //object holding ajax requests
var ajaxThreadActive = 0; //variable indicating whether the ajaxQueue is currently processing or not
//Retrieve the most recent ajax Request
function getLastRequest() {
for (i in ajaxCache) {
ajaxQue.push(ajaxCache[i]);
delete ajaxCache[i];
return; //aiming to retrieve only one request at a time to catch more requests
}
//if no items exist in the cache, proceed here
ajaxThreadActive = 0; //the ajax queue is now empty
}
//Place an ajax request in an object with a specific id so that if a newer request is created before the previous ones are completed, it will replace the old one
function queRequest(ajaxObj, id) {
if (arguments.length != 2) { //id argument is optional
id = uuid++; //generate unique id by default
}
if (id in ajaxCache) {
console.log('duplicate request');
}
ajaxCache[id] = ajaxObj;
if (ajaxThreadActive == 0) {
ajaxThreadActive = 1;
getLastRequest(); //retrieve the most 'updated' ajax request
fireOffAjaxQue();
} else {
return 'ajax thread is running';
}
}
//Initiate the ajax queue
function fireOffAjaxQue () {
if ((ajaxQue.length > 0) && ajaxThreadActive == 1) {
$.ajax(ajaxQue[0]).always( function () {
setTimeout(function () {
getLastRequest(); //retrieve the latest ajax request
fireOffAjaxQue();
}, 50); //trigger another ajax request as this one has been completed.
});
ajaxQue.shift(); //execute this immediately after sending the ajax request, executed before the .always() function
}
}
The usage is straightforward, rather than using standard jQuery:
$.ajax({url: 'someplace.php',
data: dataVar,
success: function(data) {...});
Use the following method instead:
//create ajax object
var ajaxObj = {url: 'someplace.php',
data: dataVar,
success: function (data) {...}};
//add ajax object to the queue
Then add it to the Queue like so:
queRequest(ajaxObj); //send to queue without an id as it's a unique request
// *******OR********
queRequest(ajaxObj, id); //send to the queue with an id IF there is a need to replace any existing requests with the same id
I have integrated an AjaxCache to store the latest ajax requests. For instance, in situations where multiple requests are made on a user's keystroke, sometimes you just need to send the most up-to-date request (such as form information). This manager handles the requests and assigns optional ids so that a new request can override an older request with the same id.
//for example, I utilize it this way on my webpage
queRequest(ajaxObj, 'table1Data');
Now, even if the queue is still processing requests, any calls made with 'table1Data'
will only update the ajaxObj with the given id 'table1Data'
, ensuring only essential Ajax requests are sent out.