Reputation: 23
my Ajax calls don't seem to be asynchronous when wrapped inside a .each loop, instead they seem to wait for each to finish before calling the next one ..
MVC C#:
[HttpPost]
public JsonResult DoActionGetNextStep(JSONSubmission Submission)
{
SomeStruct body = new SomeStruct();
DateTime start = DateTime.Now;
try
{
System.Threading.Thread.Sleep(5000);
body.html= "There, done";
}
catch (Exception e)
{
body.html= "There was an error: "+e.Message;
}
TimeSpan s = DateTime.Now - start;
ast.Html = body.html+ "<p> c# took " +s.Seconds +"s</p>";
return Json(body);
}
JQuery:
function DoActions(targets) {
$(targets).each(function () { DoAction($(this)); });
}
function DoAction(target) {
var parent = $(target).parents('div.actionReplaceable');
var JSONSubmission = { Data : "somedata" };
var Submission = JSON.stringify(JSONSubmission, null, 2);
$.ajax({
type: 'POST',
url: '/Main/DoActionGetNextStep',
data: Submission,
async: true,
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function (Result) {
var html = Result.html;
$(parent).html(html);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
$(parent).html("JQuery Error: " + textStatus + "\n" + errorThrown);
}
});
}
This ends up taking 25 seconds for 5 elements, each of them reporting that their call took 5 seconds. I thought ajax calls were asynchronous, so this operation should take 5 seconds total? Both server and browser are running on my localhost. Can anyone spot what I'm missing?
Upvotes: 2
Views: 912
Reputation: 338426
Your requests should be asynchronous. Check with console.log
in the appropriate places to see when things happen.
$(targets).each(DoAction);
function DoAction() {
var $parent = $(this).parents('div.actionReplaceable'),
JSONSubmission = { Data : "somedata" };
console.log("sending request for " + this-id);
$.ajax({
type : 'POST',
url : '/Main/DoActionGetNextStep',
data : JSON.stringify(JSONSubmission, null, 2),
contentType : 'application/json; charset=utf-8',
success : function (Result) {
console.log("received response for " + this-id);
$parent.html(Result.html);
},
error : function (XMLHttpRequest, textStatus, errorThrown) {
console.log("received error for " + this-id);
$parent.html("JQuery Error: " + textStatus + "\n" + errorThrown);
}
});
}
target
parameter. jQuery sets this
correctly for callback functions.target
parameter you just need to pass the function reference to .each()
.dataType: 'json'
is wrong.async: true
is superfluous unless you configured the global Ajax options to be async: false
. Which I hope you did not.Upvotes: 0
Reputation: 79033
There are two reasons why Ajax calls aren't processed in parallel:
Most browsers limit this, either because they only use two connections to each site they contact or because they explicitly limit concurrent Ajax calls.
If you access the session state in an ASP.NET application (MVC or not), you'll also run into an exclusive lock that causes parallel connections to wait. For MVC, there's an attribute to indicate that your controller action only requires read-only access to the session state to work around that.
Upvotes: 2