почему мы не можем использовать async: true в цикле? - PullRequest
0 голосов
/ 01 июля 2018

Я прошел через вопрос Javascript - запрос AJAX внутри циклов . Я понял вопрос и ответ.

var totalQuotes = 1;
var url = http://whisperingforest.org/js/getQuote(1).php;
var amount =0;
var sum = 0;
var bookingAmount = 0;
    while (counter < 6) {
      $.ajax({
        url:url,
        async: false,
        dataType: 'json',
        success:function(data) {
          jQuery.each(data, function(index, item) {
            amount = amount + item.amount;
            sum = sum + item.sum;
            bookingAmount = bookingAmount + item.bookingAmount;
          });
          $('.amount').val(amount);
          $('.sum').val(sum);
          $('.bookingAmount').val(bookingAmount);
        }
      });
      totalQuotes++;
      url = "http://whisperingforest.org/js/getQuote(" + totalQuotes + ").php";
      counter++;
    }

В приведенном выше коде, почему мы не можем использовать async:true? В чем будет проблема, если мы будем его использовать?

1 Ответ

0 голосов
/ 01 июля 2018

async:false устарело по уважительной причине: оно блокирует пользовательский интерфейс до завершения запроса, что не совсем идеально с точки зрения удобства использования. Никогда не используйте async:false.

По умолчанию async:true (или просто полное пропускание строки async) - это то, что вам нужно. «Проблема» с асинхронным кодом, на которую, я подозреваю, вы ссылаетесь, заключается в том, что вы просто должны помнить, что код асинхронный! Многие разработчики, плохо знакомые с асинхронностью, пытаются трактовать свой асинхронный код как синхронный и заканчивают тем, что пытаются манипулировать результатами вызовов XHR до того, как они вернутся.

В качестве одного из примеров такого рода вещей, которые могут сбить людей с толку, см. console.log(counter) ниже: он всегда показывает «6» вместо того, чтобы считать от 0 до 5, как и следовало ожидать, если код был синхронным. Причина этого заключается в том, что все итерации цикла while выполняются до первого асинхронного ответа, поэтому к моменту запуска первой функции success счетчик уже достиг своего максимального значения.

// your JSON source doesn't exist; replacing with this sample just for demo:
var url = "https://cors-anywhere.herokuapp.com/https://jsonfeed.org/feed.json";
var counter = 0;
while (counter < 6) {
  $.ajax({
    url: url,
    dataType: 'json',
    success: function(data) {
      console.log("AJAX success: ", data.title)
      console.log("counter: ", counter); // <-- A common mistake: this will always be 6
    }
  });
  // console.log(data)    // <-- another common mistake: trying to use the results of the XHR call before it returns
  counter++;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Другие потенциальные опасности могут включать в себя вызовы ajax, возвращающиеся в «неправильном» порядке (нет гарантии, что каждый запрос будет занимать одинаковое количество времени), или (как в вопросе, с которым вы связаны) ошибки сервера или плохие условия в сети, вызывающие некоторые из просьб никогда не возвращаться вообще.

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

Код в вашем вопросе не демонстрирует проблему, показанную в моем примере здесь, потому что вы (правильно) только пытаетесь изменить свои переменные в функциях success, и (потому что вы просто делаете сложение) это не Неважно, в каком порядке звонки возвращаются.

Вы могли бы добиться небольшого прироста производительности, пакетируя вызовы XHR вместе и вставляя результаты в DOM только после того, как все они завершены; но только для шести итераций это может не стоить хлопот.

TL; DR: ваш код в порядке, как есть (при условии, что вы исправите синтаксические ошибки и используете реальный URL JSON, как отмечено в комментариях выше).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...