【问题标题】:JQuery AJAX request behaving synchronous for unknown reason由于未知原因,JQuery AJAX 请求表现同步
【发布时间】:2011-07-19 23:42:48
【问题描述】:

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

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

想法?我觉得这一定是我忽略的显而易见的事情。

【问题讨论】:

    标签: jquery ajax asynchronous


    【解决方案1】:

    我认为 MGM 观察到的并行执行的实际问题已被忽略 因为他将时间记录作为“成功”功能的一部分。 他对异步进行了一般性的解释。然而,作为答案的请求的性质, 这里有问题。

    看下面的sn-p:

        $(function() {
            $(".dd").each(function() {
                var obj = $(this);
                $.get("test.txt", function(data) {
                    obj.html(data);
                });
            });
        });
    

    它加载一个文件(我希望是异步的)并显示它(当然是同步的)。

    但是,代码在第一个页面加载和页面刷新期间执行不同。 我正在使用 Windows 上 Firefox 4.0 中的 firebug Net 面板监视对服务器的请求。 在第一页加载(或使用 Ctrl-F5 刷新时)我可以在网络面板上看到 对“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 并不执行异步。调用服务器。

    关于为什么会发生这种情况的任何想法?

    附: 抱歉系统不允许我发布图片。

    【讨论】:

      【解决方案2】:

      试试这个吧……

      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】:

        您的调试输出全部来自success 函数,该函数在请求完成且结果到达后被调用。即使请求是异步完成的,结果进来的时候也是一个接一个的处理。

        在您的示例中,您可能启动了五个请求,它们在后台同时运行(异步)。一旦第一个结果出现,浏览器就会调用第一个success 函数,它会为您提供f1 函数的调试输出。完成此处理后,浏览器会查看同时完成的更多请求并继续为这些请求调用 success 函数。

        ajax 请求的结果可能与您请求它们的顺序相同,以便您按顺序获取日志消息。但是也有可能一个请求需要更长的时间,例如您在f3 之前获得f4 的日志输出,因为该结果到达得更早。

        【讨论】:

        • 你说得完全正确 - 我只是在 ajax 调用之前添加了控制台输出,它们确实以不同于发送的顺序返回,所以它们实际上是异步的。我的问题似乎是 UI 锁定某些作业的成功会造成请求阻塞的印象。
        【解决方案4】:

        我认为你们都混淆了这两个术语。就 AJAX 和 JQuery 而言,异步只是意味着 HTTP 请求消息将被发送到 Web 服务器,而不会在客户端造成任何延迟。这些请求很可能会按顺序发布到服务器,但我认为不能保证。我认为您正在考虑线程......

        在浏览器的 javascript 解释器等待 AJAX 响应时,同步调用可能会导致客户端延迟。

        举个简单的例子,假设您有一个 AJAX 调用,用于获取美国某个州的税率。如果是同步调用,那么结帐工具将停止计算,并且任何与 Javascript 的用户交互都不会产生响应,直到收到 AJAX 响应(带有税率)。

        在上述异步情况下,您可以定义一个回调函数,该函数将在收到 AJAX 响应后继续计算最终结帐价格。

        【讨论】:

        • 我知道这很愚蠢。我在 ajax 调用之外添加了调试代码(就像我应该做的那样),它们的行为确实是异步的。我想象他们将在自己的线程中执行,这导致了我对错误的看法。感谢您清理一切!
        猜你喜欢
        • 2011-08-11
        • 1970-01-01
        • 2011-10-04
        • 1970-01-01
        • 1970-01-01
        • 2021-09-01
        • 2012-12-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多