2016-04-02 4 views
1

Я пытаюсь выполнить обратный вызов после нескольких jQuery Ajax имеет завершено.
В моем коде оба запроса Ajax вызывают другую функцию, и когда я пытаюсь использовать эти функции, я получаю undefined.
Я думаю, что проблема связана с использованием отложенных/обещаний, но я не знаю, как их использовать.
Как выполнить обратный вызов после завершения нескольких запросов Ajax?

Вот мой код:

<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> 

ответ

0

Вы могли бы назвать createStatusView();, а затем вызвать createStatusView2(); после всех ваших запросов Ajax сделаны

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

У меня есть два отдельных вызова JQuery AJAX внутри функции ** getSpecifiedList (listName, userId) **. После каждого вызова AJAX я использую для вызова ** buildObject() **, так что это 2 раза. Я хочу, чтобы ** createStatusView() ** запускался 1 раз, после того как оба вызова AJAX завершают функцию ** buildObject() **. Итак, решение, которое вы рекомендовали, в данный момент не работает. Я что-то пропустил в вашем ответе? –

0

Метод один:

На этот раз мы 'ждал запроса к в полном размере вместо того, чтобы ждать запроса го по успеха

$(".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>"); 
}); 


Также вы можете взглянуть на ответ Ajax, используя request.responseText это может быть полезно в случае, если вы хотите, чтобы перепроверить ответ может.

Для получения дополнительной информации о jQuery.ajax вы можете прочитать документы here

+0

Вы никогда не должны устанавливать опцию 'async' на' false'. – Bergi

+0

Есть ли ошибка, проблема или проблема, о которой я не знаю или это чисто мнение основано? –

+0

Это эффективно не рекомендуется. И висит пользовательский интерфейс. Вы всегда хотите, чтобы ваши сетевые операции были асинхронными. – Bergi

0

Я не знаю, если это сделает ваш код грязным, но я хотел бы использовать флаг в этом случае

например:

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 на единицу и вызывать функцию checkAjaxCalls из обоих ответов Ajax.

+0

Не грязный, но излишне сложный и подверженный ошибкам. Просто используйте обещания. – Bergi

Смежные вопросы