【问题标题】:Most efficient way to queue up AJAX requests, given that I need input from previous ones?考虑到我需要以前的输入,最有效的排队 AJAX 请求的方法是什么?
【发布时间】:2016-05-10 20:24:17
【问题描述】:

我正在 SharePoint 中构建一个需要发出三个单独的 AJAX 请求的应用程序:

  • 为帐户 ID 具有特定职位的所有人 (searchUsers) 调用 Search API。
  • 使用在 searchUsers (getUserProps) 中检索到的每个帐户名调用用户配置文件 API。
  • 使用在 getUserProps 中检索到的经理帐户名称(第二个 getUserProps),为每个用户的经理姓名再次调用 User Profile API。

我在上面用括号括起来的三个操作是我正在编写的自定义库的一部分,以减轻一遍又一遍地编写 ajax 对象的繁重工作。不知道你们都需要看到多少库,我不想用一堆代码来解决这个问题,所以我在this jsfiddle 中添加了库的操作部分。

所以,这主要是因为我对延迟承诺和 ajax 的来龙去脉(通常可能还有整个语言)缺乏了解。但如果可能的话,我想在没有一堆嵌套函数的情况下完成上述操作。或者想知道实现这一目标的最佳实践/最有效的方法。

更新
根据 Vadim Gremyachev 的建议,我采用了jQuery.when 方法:

searchPeople().then(function(result){

    //prepare promises 
    var promises = result.items.map(function(q){
        return getUserProps(q.Manager);
    });

    //resolve for each of the promises
    $.when.apply($, promises).then(function(){
        console.log('Promises resolved.')
    });

})
.fail(function(error){
    console.log(JSON.stringify(error));  
});

function searchPeople(){
    var api = new ApiHelper('https://sharepoint/sites/subsite');

    var options = {
        query:'Job Title',
        props:['Manager']
    };        
    return api.searchUsers(options);
}

function getUserProps(account){
    var api = new ApiHelper('https://sharepoint/sites/subsite');
    var encName = encodeURIComponent(account);
    return api.getUserProperties(encName);
}

您会注意到,在$.when.applyline 中,我刚刚收到了控制台喊声。这是因为我无法得到解决的承诺。我可以在开发人员工具中看到我所有的 getUserProperties 调用都在运行。但他们永远不会解决,“承诺已解决”的调用永远不会发生。

帮助?

【问题讨论】:

  • 您应该始终使用then 而不是done,以允许链接。

标签: jquery ajax promise


【解决方案1】:

更好的选择是为每个搜索结果行返回 promise:

api.searchUsers(options).done(function(data){
   var admins = data.items;
   var promises = admins.map(function(item){
       var accountName = admins[i].AccountName;
       return getUserProperties(accountName);
   });


});

然后使用jQuery.when()解决所有承诺:

$.when.apply($, promises).then(function () {
      for (var i = 0; i < arguments.length; i++) {
        var profileProperties = arguments[i][0];  
        console.log(profileProperties.DisplayName);
      }
   }); 

示例

function searchPeople()
{
    var requestUrl = _spPageContextInfo.webAbsoluteUrl + "/_api/search/query?querytext='*'&sourceid='b09a7990-05ea-4af9-81ef-edfab16c4e31'";
    return $.getJSON(requestUrl);
}



function getUserProperties(account){
    var encName = encodeURIComponent(account);
    var requestUrl = _spPageContextInfo.webAbsoluteUrl + "/_api/SP.UserProfiles.PeopleManager/GetPropertiesFor(accountName=@v)?@v='" + encName + "'";
    return $.getJSON(requestUrl);
}


searchPeople()
.then(function(result){

   //prepare promises 
   var promises = result.PrimaryQueryResult.RelevantResults.Table.Rows.map(function(r){
       var accountName = r.Cells[3].Value;
       return getUserProperties(accountName);
   });

   //resolve for each of the promises
   $.when.apply($, promises).then(function () {
      for (var i = 0; i < arguments.length; i++) {
        var profileProperties = arguments[i][0];  
        console.log(profileProperties.DisplayName);
      }
   });

})
.fail(function(error){
   console.log(JSON.stringify(error));  
});

【讨论】:

  • 这太棒了,正是我想要的。一旦我弄清楚如何将另一个 ajax 请求加载到流程中,我将使用最终产品编辑我的问题。谢谢!
  • ...我无法让它工作。更新了我上面的代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-29
  • 2011-05-13
相关资源
最近更新 更多