由于未知原因,JQuery AJAX请求表现同步

时间:2011-03-21 20:28:39

标签: jquery ajax asynchronous

我有以下代码,我希望异步运行,但日志显示它们正在同步运行。

$(".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.

思考?我觉得这一定是显而易见的,我忽略了。

4 个答案:

答案 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。 抱歉系统不允许我发布图片。

相关问题