Подтвердить что ты не робот

JQuery: Почему $.ajax() не дождался завершения запроса перед возвратом?

Я только что потратил 3 часа на отладку кода немного, чтобы найти, что он был вызван мной, предполагая, что порядок выполнения следующего кода был линейным: -

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

Это не первый случай, когда это вызвало у меня проблемы, и мне просто интересно, в чем причина этого поведения?

Это так, что любые запросы ajax не поддерживают другое выполнение script, которое может быть не связано с запросом ajax?

4b9b3361

Ответ 1

Большинство других ответов отвечают, как справиться с этим. Я хотел бы очень кратко взглянуть на то, почему асинхронность в этом случае хорошая.

На самом деле, большинство в браузере Javascript асинхронны. Возьмем, к примеру, этот код:

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

Что будет работать первым? Вы не знаете, из-за асинхронности, присущей модели браузера (или, фактически, коду, управляемому событиями). Вы запускаете код, когда происходит событие. Вы настроили документ, затем дождитесь, когда произойдет событие, и ваш код может быть выполнен во всех видах разных заказов, в зависимости от того, какие события произойдут первыми. Код Javascript должен выполняться в течение всего срока службы страницы, а не только при ее создании.

Таким образом, в целом программирование на Javascript (или, по крайней мере, программирование на Javascript за простейшим уровнем) часто будет асинхронным. Кроме того, для HTTP-запросов очень важно, чтобы HTTP-запросы были асинхронными.

Во-первых, поскольку вы подразумеваете в своем вопросе, что синхронный код блокирует выполнение. То есть вы, вероятно, не хотите, чтобы анимация оживала две секунды, чтобы начать, потому что вы делаете HTTP-запрос двумя строками дальше. Время отклика сервера может быть (а) нерегулярным и (б) медленным, поэтому нет смысла проектировать приложение в зависимости от скорости ответа сервера.

Во-вторых, и что более важно, ваш пользователь не собирается останавливать использование страницы, потому что ваш script выполняет вызов AJAX. Вашему пользователю все равно. Возможно, ваш пользователь позаботится о том, чтобы ваше нормальное поведение onscroll не работало, потому что ваш script в настоящее время связан с несвязанным запросом AJAX. Чтобы связать с асинхронным характером всего программирования Javascript для браузера, подавляющее большинство HTTP-вызовов должно быть неблокирующим, асинхронным.

Ответ 2

, потому что ajax является асинхронным. если вы хотите что-то выполнить при успешном вызове ajax, используйте событие успеха

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

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

Asynchronous означает?

Асинхронный ввод-вывод или неблокирующий ввод-вывод - это форма ввода/вывода обработки, которая позволяет продолжить обработку до передача завершена. Асинхронный ввод-вывод используется для повышения пропускной способности, латентности и/или отзывчивости.

Ответ 3

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

Ответ 4

Чтобы задержать завершение 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

Вы можете добиться успеха, или вы также можете использовать .done();

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

Ответ 6

$.ajax является асинхронной функцией и, как таковая, не ждет завершения запроса, перед возвратом. Вместо этого, когда запрос завершен, он вызывает функции обратного вызова, которые вы указываете с помощью success и/или error.

Если вам действительно нужен синхронный bahviour, вы можете установить для параметра async значение false. (см. document). Но в этом случае имейте в виду, что весь пользовательский интерфейс зависает до завершения запроса!

Ответ 7

Как говорили другие, ajax означает Асинхронный Javascript и Xml. При этом вы можете выполнить одно из следующих действий с помощью функции jquerys ajax:

  • Установите для параметра "async" значение false, если вы хотите, чтобы вызов был синхронным. Это верно по умолчанию. См. Документы. Начиная с jQuery 1.8, использование этого свойства устарело.

  • Обеспечьте "полный" обратный вызов. Это будет происходить асинхронно по умолчанию. Это:

    Функция, вызываемая при завершении запроса (после успеха и обратные вызовы ошибок).

  • Предоставить обратный вызов "success". Это будет происходить асинхронно по умолчанию. Это:

    Функция, вызываемая при успешном выполнении запроса.

Ответ 8

Первый A в AJAX означает Асинхронный; это означает, что вызовы AJAX выполняются в фоновом режиме и не удерживают выполнение script до тех пор, пока они не будут завершены. Это в значительной степени по дизайну.

Если вы хотите запустить код при завершении вызова, вы можете передать функцию одним или несколькими из следующих параметров:

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

Ответ 9

Другой вариант - просто установить async на false

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

Таким образом, ваш следующий оператор не будет выполнен, пока не будет завершен оператор $.ajax.