【问题标题】:How can I execute callback after multiple Ajax requests complete? [duplicate]多个 Ajax 请求完成后如何执行回调? [复制]
【发布时间】:2016-07-22 05:17:58
【问题描述】:

我正在尝试在多个 jQuery Ajax 完成之后执行回调。
在我的代码中,两个 Ajax 请求都调用了另一个函数,当我尝试使用这些函数时,我得到 undefined
我认为问题与使用延迟/承诺有关,但我不知道如何使用它们。

这是我的代码:

<link rel="stylesheet" type="text/css" href="https://tag/sites/ocean1/maker/captions/shared%20documents/Web_ComplianceCSS.txt">
<div id = "cabbage" style="font-size:10px">
  <p>Web Compliance Stats</p>
</div>
<script type = "text/javascript">
  var WebComplianceReportApp = {} || WebComplianceReportApp;
  WebComplianceReportApp.GetStatuses = (function() {
    var pub = {},
      _userId,
      _ultimateObjectHolderArr = [],
      _items = [],
      _options = {
        listName: "M_Web_Compliance",
        container: "#cabbage",
      };
    pub.init = function() {
      var clientContext = new SP.ClientContext.get_current();
      _userId = clientContext.get_web().get_currentUser();
      clientContext.load(_userId);
      clientContext.executeQueryAsync(getUserInfo, _onQueryFailed);
    };

    function getUserInfo() {
      _userId = _userId.get_id();
      getSpecifiedList(_options.listName, _userId);
    }

    function buildObject(results, listName) {
      _items = results.d.results;
      $.each(_items, function(index, item) {
        _ultimateObjectHolderArr.push({
          "Division": item.ParentOrg,
          "ORG": item.ORG,
          "URL": item.URL,
          "Status": item.Site_Status
        });
      });
      //createStatusView2(_ultimateObjectHolderArr);
    }

    function getSpecifiedList(listName, userId) {
      var counter = 0;
      var baseUrl = SP.PageContextInfo.get_webServerRelativeUrl() + "/_vti_bin/listdata.svc/" + listName;
      var url1 = baseUrl + "?$select=ParentOrg,ORG,URL,Site_Status&$inlinecount=allpages";
      var call1 = $.ajax({
        url: url1,
        type: "GET",
        headers: {
          "accept": "application/json;odata=verbose",
        }
      }).done(function(results) {
        buildObject(results, listName);
      }).fail(function(error) {
        console.log("Error in getting List: " + listName);
        $(_options.container).html("Error retrieving your " + listName + ". " + SP.PageContextInfo.get_webServerRelativeUrl());
      });
      var url2 = baseUrl + "?$select=ParentOrg,ORG,URL,Site_Status&$inlinecount=allpages&$skiptoken=1000";
      var call2 = $.ajax({
        url: url2,
        type: "GET",
        headers: {
          "accept": "application/json;odata=verbose",
        }
      }).done(function(results) {
        buildObject(results, listName);
      }).fail(function(error) {
        console.log("Error in getting List: " + listName);
        $(_options.container).html("Error retrieving your " + listName + ". " + SP.PageContextInfo.get_webServerRelativeUrl());
      });
    }

    function createStatusView2(Arr) {
        var divisionArr = [];
        var oRGArr = [];
        var divisionCount = 0;
        var oRGCount = 0;
        for (var i = 0; i < Arr.length; i++) {
          if ($.inArray(Arr[i].Division, divisionArr) === -1) {
            divisionArr.push(Arr[i].Division);
            var divisionHolderElement = $("<div id='p_" + Arr[i].Division + "' class='division_row_holder'></div>");
            var divisionElement = $("<div id='" + Arr[i].Division + "' class='division_div ORG'></div>").text(Arr[i].Division);
            $("#cabbage").append(divisionHolderElement);
            $(divisionHolderElement).append(divisionElement);
          }
          if ($.inArray(Arr[i].ORG, oRGArr) === -1) {
            oRGArr.push(Arr[i].ORG);
            var orgElement = $("<div class='org_div ORG' id='" + Arr[i].ORG + "' style='font-size:10px;'></div>").text(Arr[i].ORG);
            $("#p_" + Arr[i].Division).append(orgElement);
          }
        }
      }
    //automatically fired by init
    function _onQueryFailed(sender, args) {
      alert('Request failed.\nError: ' + args.get_message() + '\nStackTrace: ' + args.get_stackTrace());
    }
    return pub
  }());
  $(document).ready(function() {
    SP.SOD.executeFunc('sp.js', 'SP.ClientContext', function() {
      //After the SP scripts are run, we access the WebComplianceReportApp.GetStatuses
      WebComplianceReportApp.GetStatuses.init();
    });
  });
</script>

【问题讨论】:

    标签: javascript jquery ajax jquery-deferred


    【解决方案1】:

    您可以调用createStatusView();,然后在完成所有Ajax 请求后调用createStatusView2();

    $(document).ready(function(){
      createStatusView();
      $(this).ajaxStop(function() {
        // NOTE: I did not see you use createStatusView(); in your code
        createStatusView2();
      });
    });
    

    【讨论】:

    • 我在一个函数 getSpecifiedList(listName, userId) 中有两个单独的 AJAX jQuery 调用。在每次 AJAX 调用之后,我使用 done 调用 buildObject(),所以是 2 次。在两个 AJAX 调用完成 buildObject() 函数之后,我只希望 createStatusView() 运行 1 次。因此,您推荐的解决方案目前不起作用。我在您的回复中遗漏了什么吗?
    【解决方案2】:

    方法一:

    这一次我们将等待请求完成,而不是等待请求成功

    $(".ajax-form-button-thingy").on("click", function() {
      $.ajax({
        url: $(this).attr("href"),
        type: 'GET',
        error: function() {
          throw new Error("Oh no, something went wrong :(");
        },
        complete: function(response) {
          $(".ajax-form-response-place").html(response);
        }
      });
    });
    

    方法二:

    如果您想等待所有 Ajax 请求完成而不将async 选项更改为false,那么您可能正在寻找jQuery.ajaxComplete();

    在 jQuery 中,每次 Ajax 请求完成时都会触发 jQuery.ajaxComplete(); 事件。

    这里是一个简单的例子,但有更多关于jQuery.ajaxComplete(); 的信息超过here

    $(document).ajaxComplete(function(event, request, settings) {
      $(".message").html("<div class='alert alert-info'>Request Complete.</div>");
    });
    


    您还可以使用 request.responseText 查看 Ajax 响应,如果您想仔细检查响应,这可能很有用。

    有关 jQuery.ajax 的更多信息,您可以阅读文档here

    【讨论】:

    【解决方案3】:

    我不知道这是否会使您的代码变脏,但在这种情况下我会使用 标志

    例如:

    var ajaxCalls = 0;
    function checkAjaxCalls()
    {
       if (ajaxCalls == 2)
       {
        //do your thing...
        //and maybe you want to reset ajaxCalls value to zero if needed...
       }
    }
    

    从每个 Ajax 响应完成后,将 ajaxCalls 变量加一,并从您的两个 Ajax 响应中调用 checkAjaxCalls 函数。

    【讨论】:

    • 不脏,但不必要的复杂且容易出错。只需使用承诺。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-28
    • 1970-01-01
    • 2018-11-08
    • 2011-08-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多