Reputation: 13921
I'm working on an application where a user fills out a lengthy form. After moving off of each field, a client side "save" function is called which ends up executing an $.ajax() call. While this is happening, a "spinner" icon is displayed next to the field to let the user know that a save is occurring.
My problem is that in older browsers (IE7+8) these take can take several seconds (there's a lot of client side stuff that happens after the save - they're complex forms and the response from the save may or may not render new form fields based on the answer they provided). During the save, the UI appears to lock up a little bit preventing users from interacting with other form elements until the save finishes.
What I'd LOVE to be able to do is run the "save" calls and allow the user to continue interacting with the site while it happens. Is there a way to allow this to happen? Here's the current code we're using:
function saveField(reviewData, isIdField) {
$.ajax({
type: "POST",
url: serviceUrl,
data: JSON.stringify(data),
contentType: "application/json; charset=utf-8",
dataType: "json",
processdata: true,
success: serviceSuccess,
error: serviceFailed
});
}
The serviceSuccess
function is pretty jQuery intensive and does a lot of UI manipulation.
EDIT: The serviceSuccess
function is too complex to warrant posting on SO. Based on the comments + posted answer, it looks like I can't get this to TRULY run asynchronously, but maybe the suggestions by @surui will bear some fruit. Also, I'll look at cleaning up this code, which I was going to do anyways. Thanks for the responses.
Upvotes: 1
Views: 445
Reputation: 1542
If I understand correctly your problem is not with the ajax operation, but rather the serviceSucess
function, as it is executed synchronously. So I guess a better answer could be provided if we saw this function implementation. Generally, you shouldn't have long sync-functions in javascript. I could suggest something, though (with a warning)
let's say you can divide your code to 4
a(response);
b(response);
c(response);
d(response);
each takes 100ms, together it's 400ms
if they can run on parallel (meaning, the order doesn't matter, in javascript you can't run things in parallel) we could write it as follows:
setTimeout(function(){
a(response);
}, 0);
setTimeout(function(){
b(response);
}, 0);
setTimeout(function(){
c(response);
}, 0);
setTimeout(function(){
d(response);
}, 0);
(or you could use async.parallel)
if they should run in series you could use async.series (similar to async.parallel), or plain java script (just nest the setTimeout-s) to:
async.series({
a: function(callback){
a(response);
callback();
}
b: function(callback){
b(response);
callback();
}
c: function(callback){
c(response);
callback();
}
d: function(callback){
d(response);
callback();
}
}, function(err, results){
// the series has ended
});
again, what I wrote could be an overkill if we could minimize dom manipulations somehow.
Upvotes: 1