【问题标题】:jquery ajax synchronous call beforeSendjquery ajax 同步调用 beforeSend
【发布时间】:2011-02-11 15:49:49
【问题描述】:

我有一个函数叫做:

function callAjax(url, data) {
 $.ajax(
   {
     url: url, // same domain
     data: data,
     cache: false,
     async: false, // use sync results
     beforeSend: function() {
       // show loading indicator
     },
     success: function() {
       // remove loading indicator 
     }
   }
  );
}

在代码中,我调用“callAjax”X 次,我想同步更新数据。它按预期完成,但有一个问题:加载项未显示在 beforeSend 函数中。如果我将 async 设置为 true,它可以工作,但更新不会同步完成。

我已经尝试了几件事,但都没有成功。我尝试将加载指示器放在 ajax 调用之前,如下所示:

function callAjax(url, data) {
  // show loading div

  $.ajax(
    {
      // same as above
    }
   );
}

但由于某种原因,它不想显示加载指示器。当我在 beforeSend 中放置“警报”并且在这种情况下出现加载指示器时,我注意到一个奇怪的行为,但我宁愿不弹出消息框。

有什么想法吗?

【问题讨论】:

  • 如果你是同步做的,那么浏览器在更新页面之前正在等待响应。
  • 即使我将加载指示器放在 ajax 调用之前,它会停止吗?我不确定我是否遵循它的执行路径。我假设在 ajax 调用之前对页面所做的任何更新都将完成。
  • 取决于浏览器;你用什么浏览器测试?
  • 另外,如果您正在执行同步调用,那么无论如何使用“beforeSend”也没多大意义。
  • 我在 Chrome、FF 和 IE 中都试过了。在 FF 上,它按预期工作。在 IE 和 Chrome 上,它会锁定它而不显示任何内容。我尝试将加载指示器放在 ajax 调用之前(不是在 beforeSend 中,而是完全在 ajax 调用之外),但它仍然没有显示。我会假设在 ajax 之前进行的任何调用都会出现在浏览器上?

标签: javascript jquery ajax


【解决方案1】:

进行这样的同步调用就像放置一个“alert()”框。有些浏览器会完全停止他们正在做的事情,直到收到 HTTP 响应。

因此,在您的代码中,在您开始调用“$.ajax()”函数后,在收到响应之前,什么都没有发生,接下来您的代码将是“成功”处理程序。

通常,除非您真的对自己的服务器有信心,否则最好使用异步调用。当您这样做时,浏览器会立即返回工作并在后台简单地侦听 HTTP 响应。当响应到达时,将调用您的成功处理程序。

【讨论】:

    【解决方案2】:

    当你做阻塞 I/O 时,程序会暂停直到接收到输入,用 JS 的话来说,当进行同步调用时,程序会暂停并且浏览器窗口会冻结(无法进行绘制),直到收到响应.在大多数情况下,可以避免进行同步调用和任何类型的阻塞 I/O。但是,想象一下您在 java 或任何其他编程语言中制作进度条,我认为您必须生成一个不同的线程来控制进度条。

    在您的情况下要尝试的一件事是在一段时间延迟后调用 ajax 调用

    //loading div stuff, 
    //if your doing some animation here make sure to have Sufficient 
    //time for it. If its just a regular show then use a time delay of 100-200
    setTimeout( ajaxCall, 500 );
    

    EDIT ajaxcall in setTimeout, Example

    【讨论】:

      【解决方案3】:

      这就是你要找的 - .ajaxStart()

      任何ajax事件启动时都会触发

      http://api.jquery.com/ajaxStart/

      他们甚至给出了一个类似于你想要完成的具体例子:

       $("#loading").ajaxStart(function(){
         $(this).show();
       });
      

      然后您可以使用 .ajaxStop() 函数

      $("#loading").ajaxStop(function(){
            $(this).hide();
      });
      

      【讨论】:

      • 事实并非如此。这将在 ajax 调用为 async == true 时起作用,但在我们的例子中,浏览器本身会暂停线程,因此一切都被阻止(包括 UI 更新) - 浏览器只是冻结。
      猜你喜欢
      • 2013-04-09
      • 2013-03-28
      • 2013-01-13
      • 2017-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多