I have the following code which I want to be running asynchronously, 开发者_C百科but the logs are showing that they are running synchronously.
$(".widget").each(function() {
// snip - url, def, and tempParams defined here
$.ajax({
url: url,
dataType: "jsonp",
type: "POST",
data: {params: tempParams},
success: function(data) {
var st = new Date().getTime();
console.error("Start " + def.name + " @" + st);
doSomething(data);
var et = new Date().getTime();
console.error("End " + def.name + " @" + et);
console.error("Duration " + def.name + " " + (et-st) + " ms.");
}
});
The console output clearly shows the success functions executing in order, rather than asynchronously:
Start f1 @1300738891705
End f1 @1300738891744
Duration f1 39 ms.
Start f2 @1300738892746
End f2 @1300738893280
Duration f2 534 ms.
Start f3 @1300738893282
End f3 @1300738893303
Duration f3 21 ms.
Start f4 @1300738893305
End f4 @1300738893306
Duration f4 1 ms.
Start f5 @1300738893484
End f5 @1300738895609
Duration f5 2125 ms.
Thoughts? I feel like this must be something obvious that I'm overlooking.
I think you're both confusing the two terms. Asynchronous in terms of AJAX and thus JQuery just means that the HTTP Request message will be sent to the webserver without causing any delay on the client's end. The requests will more than likely post to the server sequentially, but I don't think it's guaranteed. I think you're thinking in terms of threading...
Synchronous calls may cause delay on the client side while the browser's javascript interpreter is waiting for the AJAX response.
To think of a quick example, lets say you have an AJAX call that fetches the tax rate given a USA state. If it was a synchronous call, then the checkout tool would stop calculation, and any user interaction with Javascript would not produce a response until the AJAX response (with the tax rate) was received.
In an asynchronous situation from above, you could define a callback function that would continue to calculate the final checkout price once the AJAX response was received.
You debug output all comes from the success
function that is called once the request is completed and the result arrived. Even if the requests were done asynchronously, the results are processed one after another when they come in.
In your example you probably start five requests, which run simultaneously in the background (async). Once the first result comes in, the browser calls the first success
function, which gives you the debug output for the f1
function. When this processing is done, the browser looks if more requests completed in the meantime and proceeds to call the success
functions for those requests.
The results of the ajax requests might come in in the same order as you requested them, so that you get the log messages in order. But it would also be possible that one request takes a longer time and you for example get the log output of f4
before that of f3
, because that result arrived more early.
Try this instead...
var st = new Date().getTime();
console.error("Start " + def.name + " @" + st);
$.ajax({
url: url,
dataType: "jsonp",
type: "POST",
data: {params: tempParams},
success: function(data) {
doSomething(data);
var et = new Date().getTime();
console.error("End " + def.name + " @" + et);
console.error("Duration " + def.name + " " + (et-st) + " ms.");
}
});
I believe that the actual issue with parallel execution observed by MGM has been overlooked becuse he performed time-logging as part of "success" function. He took general explanations on the asyn. nature of the requests as an answer, however, there is a problem here.
Look at the snippet below:
$(function() {
$(".dd").each(function() {
var obj = $(this);
$.get("test.txt", function(data) {
obj.html(data);
});
});
});
It loads a file (asynchronously I would expect) and displays it (synchronously of course).
However, the code executes differently during the first page load and on page refresh. I am monitoring the requests to the server using firebug Net panel in Firefox 4.0 on Windows. On the first page load (or when refreshed using Ctrl-F5) I can see on the Net panel that multiple requests to the "test.txt" start at the same time and the Net acivity mostly overlapps.
This part works as expected. The result may be processed in the browser one by one, but the requests to the server are performed in parallel.
(image:initial load) (http://i.stack.imgur.com/nSFld.gif)
It is completly different story whne user presses F5 to refresh the page. Suddenly parallelism is gone.
And same web page loads "test.txt" one by one.
(image: Subsequent refresh) (http://i.stack.imgur.com/7cYfM.gif) It becomes even more clear if I replace data display (obj.html(data);) with a simple alert: alert(data); On initial page load I get multiple alert messages on the screen at the same time. Subsequent refreshes (F5) clearly demonstrate that while one alert message is on screen no other downloads are performed (I can remove the file to see "$.get" to fail).
So in fact the $.get does not perform async. calls to the server.
Any ideas on why this happening?
P.S. Sorry system does not allow me to post images.
精彩评论