13

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

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

这不是第一次给我带来问题,我只是想知道这种行为的原因是什么?

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

4

9 回答 9

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 调用应该是非阻塞的、异步的。

于 2012-06-07T13:19:31.467 回答
10

because ajax is Asynchronous. if you want to execute something on the success of ajax call, use the success event

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

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

Asynchronous means ?

Asynchronous I/O, or non-blocking I/O, is a form of input/output processing that permits other processing to continue before the transmission has finished.Asynchronous I/O is used to improve throughput, latency, and/or responsiveness.

于 2012-06-07T13:01:50.850 回答
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?
  }
});
于 2013-05-16T08:17:10.920 回答
1

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

$.ajax( {ajax options} ).done(console.log('I was assuming this would execute once the ajax request was complete'));  
于 2012-06-07T13:04:01.517 回答
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');
  }
});
于 2012-06-07T13:01:27.087 回答
0

The first A in AJAX stands for Asynchronous; that means AJAX calls are executed in the background and do not hold up the execution of the script until they are finished. This is pretty much by design.

If you want to run some code when the call finishes, you can pass a function in one or more of the following parameters:

$.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
  }

For more info, check out the API: http://api.jquery.com/jQuery.ajax

于 2012-06-07T13:16:12.307 回答
0

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

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

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

于 2015-02-17T11:21:37.153 回答
0

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

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

于 2012-06-07T13:01:31.150 回答
0

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

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

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

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

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

    请求成功时调用的函数。

于 2012-06-07T13:12:20.970 回答