【问题标题】:Ajax Call in For Loop, For Loop Completing Before all Calls are MadeFor循环中的Ajax调用,For循环在所有调用之前完成
【发布时间】:2014-01-20 18:07:13
【问题描述】:

我创建了一个 for 循环,用于循环一个元素在容器中出现的次数。 for 循环从 HTML 中获取一些数据并创建一个 JSON url,然后返回一个值。然后应该将该值添加到 HTML 的适当位置。

问题似乎是 for 循环在所有 Ajax 调用之前完成,因此只有最后一个值被添加到 HTML。我认为我可以确保 readystate 等于 4,但该解决方案不起作用。我还尝试使用完整的,而不是成功的 Ajax 事件。有什么见解吗?这是我的代码。

for(var index = 0; index < $('#wizSteps #step6 label').length; index++){
    var priceCount;
    console.log(index);
    var currentSelect = $('#wizSteps #step6 label[data-pricepos="'+index+'"]');
    url = 'http://www.thesite.com/api/search.json?taxonomy=cat3435' + currentSelect.find('input').attr('name');
    jQuery.ajax({
        url: url,
        dataType: "JSON",
        success: function( data ){
            var totalResult = data.totalNumberOfResults;
            console.log(currentSelect);
            currentSelect.find('.itemCount').text(totalResult);

        }     
    });
}

【问题讨论】:

  • Ajax 是异步的。您按顺序启动它们,但它们将在稍后完成,可能以不同的顺序。
  • 您是否尝试在 url: url, 之前将 async: false, 添加到您的 AJAX 选项中?
  • @MonkeyZeus 我不知道他有没有,但我知道他不应该。
  • async: false 肯定会解决问题,但它会在请求期间锁定浏览器,使您的页面看起来很糟糕。 在这种情况下不要使用async: false

标签: javascript jquery ajax


【解决方案1】:

看起来您不一定需要按顺序完成请求,您只需要以有效的方式跟踪currentSelect。为此,您可以使用context ajax 选项:

for (var index = 0; index < $('#wizSteps #step6 label').length; index++) {
    var currentSelect = $('#wizSteps #step6 label[data-pricepos="' + index + '"]');
    url = 'http://www.thesite.com/api/search.json?taxonomy=cat3435' + currentSelect.find('input').attr('name');
    jQuery.ajax({
        url: url,
        dataType: "JSON",
        context: currentSelect,
        success: function (data) {
            var totalResult = data.totalNumberOfResults;
            this.find('.itemCount').text(totalResult);

        }
    });
}

【讨论】:

    【解决方案2】:

    没关系,呼叫不应该以这种方式进行。它们只是在循环中启动

    Ajax 是异步的。查询稍后完成,可能顺序不同。

    如果您想确保每次通话都已完成,然后再进行下一次通话, 必须将下一个调用集成到上一个的回调函数中。

    在您的情况下,该变量可能会在回调函数中被覆盖。 您可以在此处了解更多信息:

    与该主题相关的另一个有趣的问题/讨论:

    它不会直接回答您的问题,但有助于更深入地理解问题。 关键是您可能根本不需要循环(或者您需要,但形式完全不同)。

    【讨论】:

    • 这样好吗?结果不正确,根据问题第二段的开头。
    • 没关系,因为这是给定代码的预期行为。这是否是预期的行为是另一回事。
    • @KevinB:嗯.... 这不是 StackOverflow 的重点吗?获取不执行预期的工作的代码?
    • 当然,但是这个答案确实解释了它为什么会发生,代码并不总是需要的。更新后的答案至少给出了如何修复它的建议。
    • 是的,这样更好。 :)
    【解决方案3】:

    您应该尝试创建一个递归函数,在 ajax 调用成功后您将再次调用,这样您就可以确保只有在上一次调用完成后才会调用下一次 ajax 调用。

    【讨论】:

      【解决方案4】:

      如果您希望请求按顺序排列,您可以使用队列。

      首先建立队列:

      var queue = [],
          index,
          stepLength = $('#wizSteps #step6 label').length;
      
      for(index = 0; index < length; index++){
          var priceCount;
          console.log(index);
          var currentSelect = $('#wizSteps #step6 label[data-pricepos="'+index+'"]');
          url = 'http://www.thesite.com/api/search.json?taxonomy=cat3435' + currentSelect.find('input').attr('name');
          queue.push([url, currentSelect]);
      }
      

      然后执行串行 ajax 请求:

      function serialAjax() {
          if(queue.length === 0) {
              return;
          }
          var queueData = queue.shift(),
              url = queueData[0],
              currentSelect = queueData[1];
      
          jQuery.ajax({
              url: url,
              dataType: "JSON",
              success: function( data ){
                  var totalResult = data.totalNumberOfResults;
                  console.log(currentSelect);
                  currentSelect.find('.itemCount').text(totalResult);
                  serialAjax();
              }     
          });
      };
      // call the function
      serialAjax();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-10-18
        • 1970-01-01
        • 1970-01-01
        • 2017-07-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-25
        相关资源
        最近更新 更多