为什么我们不能在循环中使用async:true?

时间:2018-07-01 11:42:18

标签: jquery ajax loops asynchronous

我遇到了问题Javascript - AJAX request inside loops。我理解了问题和答案。

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 :(得分:1)

不推荐使用

async:false,这是有充分理由的:它会阻塞UI,直到请求完成为止,从可用性的角度来看,这并不是完全理想的。永远不要使用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函数中修改变量,并且(因为您只是在做加法)呼叫返回的顺序无关紧要。

您可以通过batching the XHR calls together取得一些适度的性能提升,并且仅在所有结果完成后才将结果插入DOM;但仅进行六次迭代可能就不值得了。

TL; DR:您的代码按原样进行即可(只要您纠正语法错误并使用上面注释中所述的真实JSON网址)即可。