Reputation: 8198
My question is a bit abstract.
We're all familiar with AJAX preloaders/spinners that come up when an AJAX request is being made. My question is how do you avoid these?
Take for example, a sortable list. When a user drags and drops items to resort them, an AJAX call is made to update the order.
Before, I would pop up a fullscreen AJAX spinner to prevent the user from doing anything until the AJAX call was complete.
My question is, how would I go about avoiding the AJAX spinner and "streamlining" ajax requests to ensure if a user initiates 20 ajax requests in 2 seconds, that they will be executed in order?
I don't really need code examples, just accepted or popular techniques/ideas. Or if I'm going completely off track here.
Thank you
Upvotes: 8
Views: 581
Reputation: 26076
update
use async javascript library instead of this to achieve what you want
old below
So far good answers in terms of using an array or queue to ensure they are loaded and returned one at a time. I would eliminate the spinner all together similar to how gmail does and only message the user only when necessary. There is no point in bothering the user about all these spinner deals. They just look like little robot a-holes anyways. Here is some code to do I whipped up.
Since I got a nod on this I will explain its features.
I write plugins so is this an idea worthy of a plugin? I don't think so but hey you never know.
var queue = [],
doRequest = function(params) {
params.running = true;
$.ajax({
url: params.url,
dataType: 'json',
success: function(d) {
params.success.call(params,d);
queue.unshift(); // Quit counting your change and move along.
if (queue.length > 0) {
doRequest(queue[0]); // Hey buddy, your next.
}
},
error: function(a,b,c) {
params.error.call(params,a,b,c);
alert('"oops"'); // Rick Perry
}
});
},
queueRequest = function(params) {
queue.push(params); // Sir, you'll need to go to the BACK of the line.
if (!queue[0].running) {
doRequest(queue[0]);
}
};
// so to use this little snippit, you just call "queueRequest" like so (over and over)
queueRequest({
url: 'someajax.abc',
success: function(d) {
// let the user know their stuff was saved etc.
// "this" will be the context of the "params"
},
error: function(a,b,c) {
// let the user know something went wrong etc.
// "this" will be the context of the "params"
}
});
And you're done.
Upvotes: 7
Reputation: 78991
Isn't this exactly why, there is an async
option in jquery?
Use async: true
to queue up the request.
Spinners are kept to avoid sending same request over and over again. Like take a case, where there is an option to enable and disable a feature... if a user click at the same button again, you are sending same request over and over again. Only use spinners in these cases.
Popping up a big box, to avoid access to the whole page... is just a stupid idea (no offence).
Use spinners, to the specific elements.. that is being processed or manipulated somehow. For the request, just use async...
CASE CLOSED ;)
Upvotes: 2
Reputation: 10154
Central request Q Having a central array, that temporary holds all request, hence pesudo code would be something like this...
var centralQ = []; //holds the entire process Q
var inProc = false; //provides an in Q proc lock
//processes the request one at a time
function reqProc() {
if( centralQ.length == 0 ) {
inProc = false;
return true;
}
inProc = false; //locks it
var req = centralQ[0];
function callBack() {
//error / res processing??
if( req.callback ) {
req.callback.apply( req, arguments ); //calls the request callback
}
window.setTimeout( reqProc, 0 ); //loop backs, uses timeOut to defer the the loop
}
//Your loader???
jQuery.get( req.url, req.data, callBack );
}
function addReq( addRequest ) {
centralQ.push( addRequest );
if( !inProc ) { //does not process if it is already running
reqProc();
}
}
You proabably need to do some error catching / retrying, but u get the rough idea.
Global Spinner Just begin fadding the in the top spinner when needed, and fading it out when not needed.
Upvotes: 2
Reputation: 1262
This answer is a bit abstract, but take a look at the jQuery Deferred object: http://api.jquery.com/category/deferred-object/
It might be helpful in your situation, since it basically adds some state info to the AJAX call that you can read/update at will.
Upvotes: 2
Reputation: 231
i suggest you jquery queue ,it help you to queue anything ,if it ajax request or animation queue...
Upvotes: 2
Reputation: 22247
You could make an "ajax request manager" that queues (and potentially bundles together) pending ajax requests. I have a complex application with many ajax-updatable controls, I show spinners only over the controls that are being updated. Since your draggable list updates just stuff on the server you can probably get away without a spinner.
Upvotes: 6
Reputation: 3214
One of the options could be creating some kind of requests queue on client. Once user sorts two items, an item is added to the queue and starts executing. If another sort happens before the first call completes, it is put in the queue and will be executing after the first finishes.
UPDATE:
You should for sure handle a case, when a synchronous request is performed. At this stage all ajax requests should be somehow stored in hidden field (just an idea) and process by server before the synchronous request itself.
Upvotes: 2