Reputation: 18465
I would like to execute an Ajax request every seconds. My next code work perfectly.
window.onload = function () {
setTimeout(doStuff, 1000); //wait before continuing
}
function doStuff() {
$.ajax({
// ...
});
setTimeout(doStuff, 1000);
};
But at this moment if I use a tool like Fiddler to block my request the system continues to send new Ajax request. I would like to queue them and send my next Ajax request only after the answer of my server. How can I do that ?
Upvotes: 1
Views: 1682
Reputation: 1776
I just ran into a similar problem and solved it, so I thought I would share my answer on SO.
Here is what I did:
//Global vars:
var ajaxQue = []; //array containing immediate que of ajax object request to be fired off
var ajaxCache = {}; //object holding ajax requests.
var ajaxThreadActive = 0; //var for indicating if the ajaxQue if currently firing off or not.
//get the last (newest) ajax Request
function getLastRequest() {
for (i in ajaxCache) {
ajaxQue.push(ajaxCache[i]);
delete ajaxCache[i];
return; //aim to only get one request at a time inorder to catch more requests
}
//if no items in the cache exist, will come here
ajaxThreadActive = 0; //ajax queue is now empty
}
//put an ajax request in an obj with a specific id so that if a newer ajax request is created before the ajax requests are finished sending, it will replace the old one
function queRequest(ajaxObj, id) {
if (arguments.length != 2) { //id argument is optional
id = uuid++; //create unique id as default
}
if (id in ajaxCache) {
console.log('duplicate request');
}
ajaxCache[id] = ajaxObj;
if (ajaxThreadActive == 0) {
ajaxThreadActive = 1;
getLastRequest(); //retrieve most 'updated' ajax request
fireOffAjaxQue();
} else {
return 'ajax thread is running';
}
}
//fire off the ajax queue
function fireOffAjaxQue () {
if ((ajaxQue.length > 0) && ajaxThreadActive == 1) { //an if check on the thread active incase I want to close this from another place in code
$.ajax(ajaxQue[0]).always( function () {
setTimeout(function () {
getLastRequest(); //retrieve most 'updated' ajax request
fireOffAjaxQue();
}, 50); //fire off another ajax request since this one has been completed.
});
ajaxQue.shift(); //perform this immediately after the ajax request is sent, will execute before the .always() function
}
}
Usage is simple, instead of what you normally do in jQuery:
$.ajax({url: 'someplace.php',
data: dataVar,
success: function(data) {...});
Change it with this:
//create ajax object
var ajaxObj = {url: 'someplace.php',
data: dataVar,
success: function (data) {...}};
//send ajax object to que
Then send it to the Que with this:
queRequest(ajaxObj); //send to que without an id since this is a unique request
// *******OR********
queRequest(ajaxObj, id); //send to the que with an id IF this is to replace any 'older' requests of the same id
I have included an AjaxCache to hold the newest ajax requests. I.e. if you have a function that sends repeated requests on a user's keystroke, sometimes you only need to send the latest, most up-to-date request (like form information). In the way this manager is made, it handles the requests to have associated ids (optional) so that a new request can replace an old request by overwriting the request with the same id.
//for an example, I use it like this in my webpage
queRequest(ajaxObj, 'table1Data');
Now, in case the queue is still firing off any requests I make with 'table1Data'
will only overwrite the ajaxObj with id 'table1Data'
and thus send only the minimal amount of Ajax requests.
Upvotes: 1
Reputation: 74076
Just move the trigger for the next request in the success handler of the request before:
function doStuff() {
$.ajax({
// ...
success: function( data ) {
// your other code
setTimeout(doStuff, 1000);
}
});
};
Upvotes: 0
Reputation: 1039060
Call the setTimeout inside the success callback:
function doStuff() {
$.ajax({
// ...
success: function(result) {
// ...
setTimeout(doStuff, 1000);
}
});
}
Upvotes: 2
Reputation: 605
I have used : http://code.google.com/p/jquery-ajaxq/ for a production application.
I have customized the code to do abort of running ajax request.
Navigational Ajax (navigating to screen) - used abort.
Data submit - used queue. Can have different queues with different names.
Upvotes: 0
Reputation: 1388
use async to make ajax requests wait until one completes first
jQuery.ajax({
url: "query.php?Time="+myTimestamp(),
async: false,
success: function(data){
jQuery.ajax({
url: "query.php?Time="+myTimestamp(),
async: false,
success: function(data){
}
});
}
});
Upvotes: 0