【问题标题】:How to merge results of two jQuery AJAX calls and use deferred/promise如何合并两个 jQuery AJAX 调用的结果并使用 deferred/promise
【发布时间】:2016-04-02 18:54:49
【问题描述】:

我正在尝试合并两个 jQuery AJAX 调用的结果。我在这里查看了其他类似的问题,但似乎都没有帮助。对于每个 ajax 调用(其中 2 个),我成功调用了函数 createStatusView 并将结果传递给它。好的部分是结果适用于两个 AJAX 调用。坏消息是我的 $.when 调用为 res1 和 res2 返回 undefined,然后将结果的 undefined 发送到我的 createStatusView。所以,我真的不想为这两个 AJAX 调用调用 createStatusView,只有 $.when。任何建议将不胜感激。

function getSpecifiedList(listName, userId){

    var url = SP.PageContextInfo.get_webServerRelativeUrl() + "/_vti_bin/listdata.svc/" + listName;

    var url1 = url + "?$select=ParentOrg,ORG,URL,Site_Status&$inlinecount=allpages";       
    var call1 = $.ajax({
        url: url1,
        type: "GET",
        headers:{"accept":"application/json;odata=verbose",
        },
        success: function(results){createStatusView(results, listName);},
        error:function(error){
            console.log("Error in getting List: " + listName);
            $(_options.container).html("Error retrieving your " + listName + ". " + 
            SP.PageContextInfo.get_webServerRelativeUrl());
        }
    });

    var url2 = url + "?$select=ParentOrg,ORG,URL,Site_Status&$inlinecount=allpages&$skiptoken=1000";
    var call2 = $.ajax({
        url: url2,
        type: "GET",
        headers:{"accept":"application/json;odata=verbose",
        },
        success: function(results){createStatusView(results, listName);},
        error:function(error){
            console.log("Error in getting List: " + listName);
            $(_options.container).html("Error retrieving your " + listName + ". " + 
            SP.PageContextInfo.get_webServerRelativeUrl());
        }
    });
    //the res1 and res2 come back undefined
            //call1 and call2 are objects as shown in F12 debug
    $.when(call1,call2).done(function(res1,res2){
        var results = res1[0].d.results.concat(res2[0].d.results);
        createStatusView(results,listName);
    });
}

【问题讨论】:

  • createStatusView 应该返回什么?您的 $.ajax 成功处理程序没有向调用者返回任何内容...您想用 ajax 调用返回的数据来提供您的 $.when.done 回调吗?
  • createStatusView 只处理数据,或者在这种情况下,处理结果并将它们显示在网页中。它可以工作,但由于代码量过多而不想包含它。如果我注释掉 $.when,两个 ajax 调用都可以正常工作,唯一的问题是 createStatusView 中发生的处理发生了两次而不是一次,我最终在我的页面上显示了两个不同的数据块,而,我想合并结果并一次处理它们,以便我的布局和逻辑正常工作

标签: javascript jquery ajax


【解决方案1】:

尝试在 $.when 回调函数中添加一些对象检测。它会将未定义的值排除在您的列表之外。

$.when(call1,call2).done(function(res1,res2){
    var results = res1[0].d.results.concat(res2[0].d.results);
    if (results) {
        createStatusView(results,listName);
    }
});

另一个例子:

$.when(call1,call2).done(function(res1,res2){
   if (!res1 && !res2) return;
   var results = res1[0].d.results.concat(res2[0].d.results);
   if (results) {
      createStatusView(results,listName);
   }
});

与此相同:

$.when(call1,call2).done(function(res1,res2){
   if (res1 && res2) {
      var results = res1[0].d.results.concat(res2[0].d.results);
      if (results) {
         createStatusView(results,listName);
      }
   }
});

【讨论】:

  • 我还添加了一些测试,但它们并没有帮助解决问题。
  • 我想我明白你真正在问什么。您正在寻找一种将 2 个对象合并在一起的方法,如下所示:var mergedResults = $.extend({},model.ajax1Results,model.ajax2Results); createStatusView(mergedResults, listName); 我已经为这个 jsfiddle 添加了一个扩展答案,有 3 个选项供您选择,但它们都需要额外的代码:jsfiddle.net/briankueck/tpgzbax4核心组件是 jQuery 的 $.extend() 函数。我的 jsfiddle 说明了如何跟踪 Ajax 回调并仅使用合并结果运行 createStatusView 函数 1x。
  • 从你的 jsfiddle 来看,我的大部分工作都在工作。对于我对 mergeCallbacks 的调用,我必须添加“ajax1Results”和“ajax2Results”的键。现在我在 mergeCallbacks 函数中,它一直工作到 $.extend。 $.extend 不起作用,我的 mergeResults 在结果 = ajax2Results 中包含 25 个对象(应该是 1025)。 ajax1Results 被忽略或覆盖。我也试过做 $.extend(ajax1Results,ajax2Results) 但它仍然只得到 ajax2Results。我重新排序了 ajax1Results 和 ajax2Results,我得到了相反的结果,即对象数组中的 1000 个对象。谢谢
  • 我根据你的脚本创建了一个 jsfiddle:https://jsfiddle.net/M_66/0taxbnw3
  • 我将 jquery ajax 结果的结构添加到我的 jsfiddle 以防万一。
【解决方案2】:

您是否尝试过将 ajax 调用移动到单独的函数,然后从何时调用它们?

function getSpecifiedList(listName, userId){
    $.when(call1(listName),call2(listName)).then(function(res1,res2){
        var results = res1[0].d.results.concat(res2[0].d.results);
        createStatusView(results,listName);
    });
}

function call1(listName){   
    var url = SP.PageContextInfo.get_webServerRelativeUrl() + "/_vti_bin/listdata.svc/" + listName;
    var url1 = url + "?$select=ParentOrg,ORG,URL,Site_Status&$inlinecount=allpages";   

    return $.ajax({
        url: url1,
        type: "GET",
        headers:{
            "accept":"application/json;odata=verbose",
        }
    }); 
};

function call2(listName){
    var url = SP.PageContextInfo.get_webServerRelativeUrl() + "/_vti_bin/listdata.svc/" + listName;
    var url2 = url + "?$select=ParentOrg,ORG,URL,Site_Status&$inlinecount=allpages&$skiptoken=1000";
    return $.ajax({
        url: url2,
        type: "GET",
        headers:{
            "accept":"application/json;odata=verbose",
        }
    });
};

【讨论】:

  • 是的,已经尝试过了。以下是结果:无法获取未定义或空引用的属性“结果”
猜你喜欢
  • 2016-07-04
  • 2012-12-04
  • 2016-09-03
  • 2021-06-25
  • 1970-01-01
  • 2018-03-07
  • 2016-08-07
  • 2012-11-03
  • 2010-11-23
相关资源
最近更新 更多