如何等待大量、任意数量的深度嵌套的异步jQuery ajax调用完成

如何等待大量、任意数量的深度嵌套的异步jQuery ajax调用完成,jquery,ajax,asynchronous,sharepoint-2013,Jquery,Ajax,Asynchronous,Sharepoint 2013,我正在使用SharePoint rest web服务界面从站点获取大量数据 这涉及到对不同服务的深度嵌套ajax调用(即获取网站,获取其列表,获取列表中的所有项目,对于每个项目,获取其属性,获取webhsite的子站点…重复) 我正在使用承诺数组,将每个调用都推送到数组中: promises.push($.ajax({ url: fullurl, method: "GET", headers: { "Accept": "application/j

我正在使用SharePoint rest web服务界面从站点获取大量数据

这涉及到对不同服务的深度嵌套ajax调用(即获取网站,获取其列表,获取列表中的所有项目,对于每个项目,获取其属性,获取webhsite的子站点…重复)

我正在使用承诺数组,将每个调用都推送到数组中:

 promises.push($.ajax({
        url: fullurl,
        method: "GET",
        headers: { "Accept": "application/json; odata=verbose" },
        success: function (data) {                  
                  $.each(data.d.results, function(i, item) {
                ProcessData(i,item, tableTarget, columns, promises);                                                
                   });      
        },
        error: function (data) {
                console.log("request failed: " + fullurl);
        }
    }));
对ProcessData的每次调用都可能向html表(“tableTarget”)添加一行,并调用更多数据

理想情况下,我希望延迟尝试筛选表的脚本,直到所有数据都存在。 问题是当我打电话给

var promises = [];
//kickoff my data gathering
AddWebData(url,tableTarget, promises);
//apply
$.when.apply($, promises).then(processFinalTable(promises));    
Promissions数组中只有大约2项,因此调用processFinalTable太早了。 如果我耽搁

setTimeout(函数(){ log('waited 4000'); $.when.apply($,承诺)。然后(processFinalTable(承诺));
}, 4000);

承诺列表中有400个左右的项目。实际上,我总共需要等待1200多个ajax调用(不问)


鉴于我将根据SharePoint网站数据进行任意数量的调用。如何确定最后一次异步调用何时完成?

类似的情况如何?将调用封装在一个函数中,该函数返回一个延迟对象,该对象在所有调用完成后得到解析。注释代码有助于澄清发生了什么:

MIN_DELAY = 200;
MAX_DELAY = 2000;

function mockAjaxCall() {
  var deferred = jQuery.Deferred();
  var ms_delay = Math.floor(Math.random() * (MAX_DELAY - MIN_DELAY + 1)) + MIN_DELAY;

  setTimeout(function() {
    deferred.resolve(ms_delay);
  }, ms_delay);

  return deferred;
}

function collectAllThatData() {
  var allCallsComplete = jQuery.Deferred();
  var callsPending = [];
  var callsComplete = [];
  var ms_interval = 250;

  // Let's mock 40 asynchronous AJAX calls with random delays
  for (var i=0; i<40; i++) {
    var promise = mockAjaxCall();
    callsPending.push(promise);
  }

  // As promises are resolved, add to callsComplete array.
  jQuery.each(callsPending, function(n, callPending) {
    jQuery.when(callPending).done(function() {
      callsComplete.push(callPending);
    });
  });

  // At defined interval, compare callsComplete to callsPending to determine
  // if all our calls are complete.
  var intervalId = setInterval(function() {
    console.log(callsComplete.length, 'calls complete');

    if ( callsComplete.length >= callsPending.length ) {
      clearInterval(intervalId);
      allCallsComplete.resolve(callsComplete);
    }
  }, ms_interval);

  // Return a deferred object for calling script to use.
  return allCallsComplete;
}

var allThatDataCollected = collectAllThatData();

jQuery.when(allThatDataCollected).then(function() {
  console.log('Data has been collected!');
  // Do something else
});
minu延迟=200;
最大延迟=2000;
函数mockAjaxCall(){
var deferred=jQuery.deferred();
var ms_delay=Math.floor(Math.random()*(MAX_delay-MIN_delay+1))+MIN_delay;
setTimeout(函数(){
延迟。解决(ms_延迟);
},ms_delay);
延期归还;
}
函数collectAllThatData(){
var allCallsComplete=jQuery.Deferred();
var CallExpanding=[];
var callsComplete=[];
var-ms_区间=250;
//让我们模拟40个具有随机延迟的异步AJAX调用
for(变量i=0;i=callexpensing.length){
clearInterval(intervalId);
allCallsComplete.resolve(callsComplete);
}
},ms_间期);
//返回一个延迟对象以调用要使用的脚本。
返回所有调用完成;
}
var allThatDataCollected=collectalthatdata();
当(收集的所有数据)。然后(函数(){
log('已收集数据!');
//做点别的
});
用小提琴演示:


不幸的是,答案是我使用了不正确的语法

我改变了:

$.when.apply($, promises).then(processFinalTable());    
致:


现在一切都正常了。

您可以让每个回调clearTimeout()和setTimeout(完成,500),where done是排序的函数。这样,URL通常会逐步进入,并通过重新延迟来阻止排序。如果它暂停一点,将调用sort,就像连接恢复后一样。如果排序不是破坏性的或发生在“折叠下”,您甚至不需要每次都重新绘制,最糟糕的情况是,您每秒只绘制两次,延迟500毫秒。提到的500毫秒实际上应该不超过这些ajax请求的平均周转时间的两倍。我可以把它作为最后的解决办法。请你帮我解决这个问题:
$.when.apply($, promises).then(processFinalTable);