我有以下代码,我希望异步运行,但日志显示它们正在同步运行。
$(".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.");
}
});
控制台输出清楚地显示了按顺序执行的成功函数,而不是异步执行:
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.
思考?我觉得这一定是显而易见的,我忽略了。
答案 0 :(得分:1)
我认为你们两个方面都很困惑。就AJAX和JQuery而言,异步意味着HTTP请求消息将被发送到Web服务器而不会导致客户端的任何延迟。请求很可能会顺序发送到服务器,但我不认为这是保证。我认为你在考虑线程......
当浏览器的javascript解释器等待AJAX响应时,同步调用可能会导致客户端延迟。
想想一个简单的例子,假设你有一个AJAX调用来获取美国州的税率。如果是同步调用,则结账工具将停止计算,并且在收到AJAX响应(具有税率)之前,任何用户与Javascript的交互都不会产生响应。
在上面的异步情况下,您可以定义一个回调函数,一旦收到AJAX响应,该函数将继续计算最终的结账价格。
答案 1 :(得分:1)
您调试输出全部来自success
函数,该函数在请求完成并且结果到达时调用。即使请求是异步完成的,结果也会在它们进入时一个接一个地处理。
在您的示例中,您可能会启动五个请求,这些请求在后台同时运行(异步)。第一个结果进入后,浏览器会调用第一个success
函数,该函数为f1
函数提供调试输出。完成此处理后,浏览器会查看在此期间是否完成了更多请求,并继续为这些请求调用success
函数。
ajax请求的结果可能与您请求的顺序相同,因此您可以按顺序获取日志消息。但是,一个请求也可能需要更长的时间,例如,在f4
之前获取f3
的日志输出,因为该结果更早到达。
答案 2 :(得分:1)
试试这个......
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.");
}
});
答案 3 :(得分:0)
我认为MGM观察到的并行执行的实际问题一直被忽视 因为他将时间记录作为“成功”功能的一部分。 他对asyn进行了一般性的解释。然而,请求的性质作为答案, 这里有一个问题。
请看下面的代码:
$(function() {
$(".dd").each(function() {
var obj = $(this);
$.get("test.txt", function(data) {
obj.html(data);
});
});
});
它加载一个文件(我希望是异步的)并显示它(当然是同步的)。
但是,代码在第一页加载和页面刷新期间执行的方式不同。 我在Windows上的Firefox 4.0中使用firebug Net面板监视对服务器的请求。 在第一页加载(或使用Ctrl-F5刷新时),我可以在Net面板上看到 对“test.txt”的多个请求同时开始,并且净活动大多数重叠。
此部分按预期工作。结果可以在浏览器中逐个处理, 但是对服务器的请求是并行执行的。
(图片:初始加载) (http://i.stack.imgur.com/nSFld.gif)
当用户按F5刷新页面时,这是完全不同的故事。突然并行性消失了 同一个网页逐个加载“test.txt”。
(图片:后续刷新) (http://i.stack.imgur.com/7cYfM.gif) 如果我用一个简单的警报替换数据显示(obj.html(data);)变得更加清晰:alert(data); 在初始页面加载时,我同时在屏幕上收到多条警报消息。 随后的刷新(F5)清楚地表明,虽然屏幕上有一条警报消息,但没有其他消息 执行下载(我可以删除文件以查看“$ .get”失败)。
所以实际上$ .get不会执行异步。调用服务器。
有关为何发生此事的任何想法?
P.S。 抱歉系统不允许我发布图片。