jQuery:为什么$ .ajax()在返回之前不等待请求完成?

时间:2012-06-07 12:59:08

标签: ajax jquery

我只花了3个小时调试一些代码才发现它是由我假设下面代码的执行顺序是线性的: -

$.ajax( {ajax options} );
console.log('I was assuming this would execute once the ajax request was complete');

这不是第一次导致我出现问题,我只是想知道这种行为的原因是什么?

是否所有ajax请求都不会阻止可能与ajax请求无关的其他脚本执行?

9 个答案:

答案 0 :(得分:12)

其他大多数答案都在回答如何解决这个问题。我想非常简短地看一下为什么异步在这种情况下是好的。

事实上,大多数浏览器内的Javascript是异步的。举个例子,这个代码:

document.getElementById('foo').onclick = function() {
    alert('foo clicked');
};
document.getElementById('bar').onclick = function() {
    alert('bar clicked');
};

哪个先运行?您不知道,因为浏览器模型固有的异步性(或实际上是大多数事件驱动的代码)。您在事件发生时运行代码。您设置文档,然后等待事件发生,并且您的代码可以以各种不同的顺序执行,具体取决于首先发生的事件。 Javascript代码需要在页面的整个生命周期内执行,而不仅仅是在第一次创建它时。

所以一般 Javascript编程(或者至少是超出最简单级别的Javascript编程)通常是异步的。此外,HTTP请求也是异步的很有意义。

首先,正如您在问题中所暗示的那样,使代码同步将阻止执行。也就是说,你可能不想让动画等待两秒钟才开始,因为你正在进行两行的HTTP请求。服务器响应时间可能是(a)不规则和(b)缓慢,因此应用程序的设计根据服务器响应的速度进行设置是没有意义的。

其次,更重要的是,您的用户不会停止使用该页面,因为您的脚本正在进行AJAX调用。您的用户不在乎。您的用户可能会关心您的正常onscroll行为无效,因为您的脚本当前与无关的AJAX请求捆绑在一起。为了配合整个浏览器Javascript编程的异步性,绝大多数HTTP调用应该是非阻塞的,异步的。

答案 1 :(得分:10)

因为ajax是异步。如果你想在ajax调用成功时执行某些操作,请使用成功事件

$.ajax({
  url: 'yourserverpage.php',
  success: function(data) {

    alert('This will be executed only when ajax call is success /finished');
  }
});

Asynchronous表示什么?

  

异步I / O或非阻塞I / O是一种输入/输出形式   允许其他处理在此之前继续的处理   传输已完成。异步I / O用于提高吞吐量,延迟和/或响应能力。

答案 2 :(得分:2)

jQuery $.ajax()提供了您可以使用的4个(事件)选项:beforeSend,success,error和complete。我认为在你的情况下,完整的将是正确的答案。

例如

$.ajax({
  url: someUrl,
  //...
  beforeSend: function(){
    console.log("I'm sending AJAX.");
    //display loading?
  },
  success: function(data){
    console.log('response: '+data);
  },
  error: function(er){
    console.log(er.responseText);
  },
  complete: function(){
    console.log("I'm done.");
    //hide loading?
  }
});

答案 3 :(得分:1)

要保持AJAX完成,您需要将代码置于success:函数中,如下所示:

$.ajax({
  url: 'ajax/test.html',
  success: function(data) {
    // Do something after AJAX is completed.
    console.log('I was assuming this would execute once the ajax request was complete');
  }
});

答案 4 :(得分:1)

您可以成功,也可以使用.done();

$.ajax( {ajax options} ).done(console.log('I was assuming this would execute once the ajax request was complete'));  

答案 5 :(得分:0)

$.ajax是一个异步函数,因此在返回之前不会等待请求完成。相反,当请求完成后,它会调用回调函数,由success和/或error指定。

如果您确实需要同步bahviour,可以将选项async设置为false。 (见docu)。但在这种情况下要注意,整个用户界面会冻结,直到请求完成!

答案 6 :(得分:0)

正如其他人所说,ajax代表异步Javascript和Xml 。话虽如此,您可以使用jquerys ajax函数执行以下任一操作:

  1. 如果您希望呼叫是同步的,请将“async”选项设置为false。默认情况下这是真的。查看文档。从jQuery 1.8开始,不推荐使用此属性。

  2. 提供“完整”回调。默认情况下,这将异步发生。这是:

      

    请求完成时要调用的函数(成功后和   错误回调被执行)。

  3. 提供“成功”回调。默认情况下,这将异步发生。这是:

      

    请求成功时要调用的函数。

答案 7 :(得分:0)

AJAX 中的第一个 A 代表异步;这意味着AJAX调用在后台执行,并且在完成之前不会阻止脚本的执行。这几乎是设计上的。

如果要在调用结束时运行某些代码,可以使用以下一个或多个参数传递函数:

$.ajax({
  // your other options

  done: function(data, textStatus, jqXHR) {
    alert('Success! I got the following data back: ' + data);
    // this runs when the request has finished successfully
  },

  fail: function(jqXHR, textStatus, errorThrown) {
    alert('Oops, there was an error :(');
    // this runs when the request has finished, but with an error
  },

  always: function(jqXHR, textStatus) {
    alert("OK, I'm done.");
    // this runs when the call is finished, regardless
    // of whether it has succeeded or not
  }

有关详细信息,请查看API:http://api.jquery.com/jQuery.ajax

答案 8 :(得分:0)

另一种选择是简单地将async设置为false

$.ajax({
  async : 'false',
  other options
});

这样,在$ .ajax语句完成之前,您的下一个语句将不会执行。