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

时间:2022-08-23 17:56:13

I've just spent 3 hours debugging a bit of code only to find it was caused by me assuming that the execution order of the following code was linear:-

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

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

This isn't the first time that this has caused me problems and I was just wondering what the reason for this behavior was?

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

Is it so that any ajax requests don't hold up other script execution that may be unrelated to the ajax request?

是为了不让任何ajax请求占用与ajax请求无关的其他脚本执行吗?

9 个解决方案

#1


12  

Most of the other answers are answering how to deal with this. I'd like to look, very briefly, at why asynchronous is good in this case.

大多数其他的答案是回答如何处理这个问题。我想简单地看看异步为什么在这种情况下是好的。

In fact, most in-browser Javascript is asynchronous. Take, for example, this code:

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

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

Which will run first? You don't know, because of the asynchronicity inherent to the browser model (or in fact most event-driven code). You run code when an event occurs. You set up the document, then wait for the event to happen, and your code could be executed in all kinds of different orders, depending on what events happen first. Javascript code needs to be executed during the whole lifetime of the page, not just when it's first created.

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

So in general Javascript programming (or at least, Javascript programming beyond the simplest level) is often going to be asynchronous. Furthermore, it makes a great deal of sense for HTTP requests to be asynchronous as well.

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

First, as you imply in your question, making the code synchronous would block execution. That is to say, you probably don't want to make an animation wait two seconds to start because you're making an HTTP request two lines further up. Server response times can be (a) irregular and (b) slow, so it makes no sense for the design of your application to depend on the speed of your server's response.

首先,正如您在问题中所暗示的,使代码同步将阻碍执行。也就是说,您可能不希望让动画等待两秒钟开始,因为您正在发出一个HTTP请求,距离较远的两行。服务器响应时间可能是(a)不规则的,(b)很慢,因此,应用程序的设计取决于服务器响应的速度是毫无意义的。

Second, and more importantly, your user isn't going to stop using the page because your script is making an AJAX call. Your user doesn't care. Your user probably will care that your normal onscroll behaviour isn't working because your script is currently tied up with an unrelated AJAX request. To tie in with the asynchronous nature of the whole of browser Javascript programming, the vast majority of HTTP calls should be non-blocking, asynchronous.

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

#2


10  

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

因为ajax是异步的。如果您想要执行ajax调用的成功,请使用success事件。

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

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

#3


2  

jQuery $.ajax() provides 4 (event) options that you could use: beforeSend, success, error, and complete. I think in your case, complete would be the right answer.

jQuery $.ajax()提供了4个(事件)选项,您可以使用:前面、成功、错误和完成。我认为在你的情况下,完全是正确的答案。

For example

例如

$.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?
  }
});

#4


1  

To hold up AJAX Completion, you need to put your code inside success: function like below:

要延迟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');
  }
});

#5


1  

You can do success or you may also use .done();

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

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

#6


0  

$.ajax is an asynchronous function and as such does not wait for the request to complete, before returning. Instead, when the request has finished, it calls the callback functions, you specify by success and/or error.

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

If you really need a synchronous bahviour you can set the option async to false. (see docu). But in that case be aware, that you whole UI freezes until the request has finished!

如果您真的需要一个同步的bahviour,您可以将option async设置为false。(见docu)。但在这种情况下,请注意,整个UI将冻结,直到请求完成!

#7


0  

As the others have said, ajax stands for Asynchronous Javascript and Xml. That being said, you can do either of the following with jquerys ajax function:

正如其他人所说,ajax代表异步Javascript和Xml。也就是说,您可以使用jquerys ajax函数做以下任何一种:

  1. Set the "async" option to false, if you want the call to be synchronous. This is true by default. See the docs. As of jQuery 1.8, the use of this property is deprecated.

    如果希望调用是同步的,请将“async”选项设置为false。这在默认情况下是正确的。看文档。在jQuery 1.8中,不赞成使用此属性。

  2. Provide a "complete" callback. This will occur asynchronously by default. This is:

    提供一个“完整”的回调函数。默认情况下将异步执行。这是:

    A function to be called when the request finishes (after success and error callbacks are executed).

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

  3. Provide a "success" callback. This will occur asynchronously by default. This is:

    提供了一个“成功”的回调函数。默认情况下将异步执行。这是:

    A function to be called if the request succeeds.

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

#8


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.

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

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

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

#9


0  

Another option is to simply set async to false

另一个选项是将async设置为false

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

This way your next statement will not be executed until the $.ajax statement is finished.

这样您的下一个语句将不会被执行直到$。ajax语句完成。

#1


12  

Most of the other answers are answering how to deal with this. I'd like to look, very briefly, at why asynchronous is good in this case.

大多数其他的答案是回答如何处理这个问题。我想简单地看看异步为什么在这种情况下是好的。

In fact, most in-browser Javascript is asynchronous. Take, for example, this code:

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

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

Which will run first? You don't know, because of the asynchronicity inherent to the browser model (or in fact most event-driven code). You run code when an event occurs. You set up the document, then wait for the event to happen, and your code could be executed in all kinds of different orders, depending on what events happen first. Javascript code needs to be executed during the whole lifetime of the page, not just when it's first created.

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

So in general Javascript programming (or at least, Javascript programming beyond the simplest level) is often going to be asynchronous. Furthermore, it makes a great deal of sense for HTTP requests to be asynchronous as well.

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

First, as you imply in your question, making the code synchronous would block execution. That is to say, you probably don't want to make an animation wait two seconds to start because you're making an HTTP request two lines further up. Server response times can be (a) irregular and (b) slow, so it makes no sense for the design of your application to depend on the speed of your server's response.

首先,正如您在问题中所暗示的,使代码同步将阻碍执行。也就是说,您可能不希望让动画等待两秒钟开始,因为您正在发出一个HTTP请求,距离较远的两行。服务器响应时间可能是(a)不规则的,(b)很慢,因此,应用程序的设计取决于服务器响应的速度是毫无意义的。

Second, and more importantly, your user isn't going to stop using the page because your script is making an AJAX call. Your user doesn't care. Your user probably will care that your normal onscroll behaviour isn't working because your script is currently tied up with an unrelated AJAX request. To tie in with the asynchronous nature of the whole of browser Javascript programming, the vast majority of HTTP calls should be non-blocking, asynchronous.

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

#2


10  

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

因为ajax是异步的。如果您想要执行ajax调用的成功,请使用success事件。

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

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

#3


2  

jQuery $.ajax() provides 4 (event) options that you could use: beforeSend, success, error, and complete. I think in your case, complete would be the right answer.

jQuery $.ajax()提供了4个(事件)选项,您可以使用:前面、成功、错误和完成。我认为在你的情况下,完全是正确的答案。

For example

例如

$.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?
  }
});

#4


1  

To hold up AJAX Completion, you need to put your code inside success: function like below:

要延迟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');
  }
});

#5


1  

You can do success or you may also use .done();

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

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

#6


0  

$.ajax is an asynchronous function and as such does not wait for the request to complete, before returning. Instead, when the request has finished, it calls the callback functions, you specify by success and/or error.

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

If you really need a synchronous bahviour you can set the option async to false. (see docu). But in that case be aware, that you whole UI freezes until the request has finished!

如果您真的需要一个同步的bahviour,您可以将option async设置为false。(见docu)。但在这种情况下,请注意,整个UI将冻结,直到请求完成!

#7


0  

As the others have said, ajax stands for Asynchronous Javascript and Xml. That being said, you can do either of the following with jquerys ajax function:

正如其他人所说,ajax代表异步Javascript和Xml。也就是说,您可以使用jquerys ajax函数做以下任何一种:

  1. Set the "async" option to false, if you want the call to be synchronous. This is true by default. See the docs. As of jQuery 1.8, the use of this property is deprecated.

    如果希望调用是同步的,请将“async”选项设置为false。这在默认情况下是正确的。看文档。在jQuery 1.8中,不赞成使用此属性。

  2. Provide a "complete" callback. This will occur asynchronously by default. This is:

    提供一个“完整”的回调函数。默认情况下将异步执行。这是:

    A function to be called when the request finishes (after success and error callbacks are executed).

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

  3. Provide a "success" callback. This will occur asynchronously by default. This is:

    提供了一个“成功”的回调函数。默认情况下将异步执行。这是:

    A function to be called if the request succeeds.

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

#8


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.

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

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

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

#9


0  

Another option is to simply set async to false

另一个选项是将async设置为false

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

This way your next statement will not be executed until the $.ajax statement is finished.

这样您的下一个语句将不会被执行直到$。ajax语句完成。