【问题标题】:How to wait for a large, arbitrary number of deeply nested async jQuery ajax calls to complete如何等待大量、任意数量的深度嵌套异步 jQuery ajax 调用完成
【发布时间】:2014-10-05 00:20:06
【问题描述】:

我正在使用 SharePoint REST Web 服务接口从网站获取大量数据。

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

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

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

promises 数组中只有大约 2 项,因此调用 processFinalTable 为时过早。 如果我耽误了

setTimeout(函数(){ console.log('等待 4000'); $.when.apply($, promises).then(processFinalTable(promises));
}, 4000);

promises 列表有 400 个左右的项目。总的来说,我实际上需要等待 1200 个奇怪的 ajax 调用(不要问)。

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

【问题讨论】:

  • 你可以让每个回调 clearTimeout() 和 setTimeout(done, 500); ,其中 done 是一个排序的函数。这样一来,URL 通常会逐步进入并通过重新延迟来阻止排序。如果它停顿了一下,就会调用排序,因为它会在连接恢复后调用。如果排序是非破坏性的或发生在“折叠之下”,你甚至不需要每次都重新绘制,最坏的情况是,你每秒只绘制两次,延迟为 500 毫秒。提到的 500 毫秒实际上应该不超过这些 ajax 请求的平均周转时间的两倍左右。
  • 我可能会将其作为最后的解决方法。

标签: jquery ajax asynchronous sharepoint-2013


【解决方案1】:

很遗憾,答案是我使用了错误的语法。

我变了:

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

到:

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

现在一切正常。

【讨论】:

【解决方案2】:

这样的事情怎么样?将您的调用封装在一个函数中,该函数返回一个延迟对象,一旦您的所有调用完成,该对象就会被解析。注释代码以帮助澄清发生了什么:

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
});

小提琴演示:

http://jsfiddle.net/klenwell/jyza3050/

【讨论】:

    猜你喜欢
    • 2012-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-18
    • 2017-08-27
    • 2016-12-20
    • 1970-01-01
    相关资源
    最近更新 更多