代码之家  ›  专栏  ›  技术社区  ›  Shailesh Jaiswal

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

  •  0
  • Shailesh Jaiswal  · 技术社区  · 6 年前

    我已经考虑过这个问题了 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 回复  |  直到 6 年前
        1
  •  1
  •   Daniel Beck    6 年前

    async:false 不推荐使用,原因很好:它会阻塞ui直到请求完成,从可用性的角度来看,这并不完全理想。从不使用 异步: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调用(不能保证每个请求将花费相同的时间),或者(如您所链接的问题中所述)服务器错误或糟糕的网络状况导致一些请求根本无法返回。

    当然,处理所有这些问题的方法都是存在的,但最重要的一点就是要首先意识到它们是可能的,所以不要把自己描绘成一个角落。

    您问题中的代码没有显示我的示例中所示的问题,因为您(正确地)只试图在 成功 函数,并且(因为您只是在做加法)调用返回的顺序无关紧要。

    你可以通过 batching the XHR calls together 只有当所有的结果都完成后才将它们插入到dom中;但是对于仅仅六次迭代来说,这可能不值得麻烦。

    tl;dr:您的代码还可以(只要您纠正语法错误并使用上面注释中提到的真正的json url)。