如何等待大量、任意数量的深度嵌套的异步jQuery ajax调用完成
我正在使用SharePoint rest web服务界面从站点获取大量数据 这涉及到对不同服务的深度嵌套ajax调用(即获取网站,获取其列表,获取列表中的所有项目,对于每个项目,获取其属性,获取webhsite的子站点…重复) 我正在使用承诺数组,将每个调用都推送到数组中:如何等待大量、任意数量的深度嵌套的异步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
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);