首页 > 解决方案 > 将多个 AJAX 调用的结果连接到单个变量中

问题描述

我想调用 2 个递归 API 调用来生成 JQuery 数据表页面日期范围 2016-2021。下面这些 API 调用的年份过滤器拆分 API 响应,以克服 Sharepoint Online 建立的 5000 项列表限制阈值。

我无法将所有结果连接到我的 var allResults 中。使用下面的代码,我只能得到 2021 年生成的结果。但是,我可以看到 2016-2021 年期间通过 Chrome XHR 进行了 12 次成功的 API 调用,但结果没有被连接到 var 中。好心提醒。

var results;
var allResults = [];

$(document).ready(function () {
    load();
});

function load() {
    for (let year = 2016; year < 2022; year++) {
        var yearh1 = $.ajax({    
            url: "SPO_Site/_api/web/lists/getbytitle('List_Name')/items?$top=5000&$select=*&$filter=(Col_Date%20ge%20datetime'"+(year-1)+"-12-31T20:00:00.000Z')%20and%20(Col_Date%20lt%20datetime'"+year+"-06-01T00:00:00.000Z')",    
            type: "GET", dataType: "json", headers: {"accept": "application/json;odata=verbose"},    
            success: mySuccHandler, error: myErrHandler}); 

        var yearh2 = $.ajax({    
            url: "SPO_Site/_api/web/lists/getbytitle('List_Name')/items?$top=5000&$select=*&$filter=(Col_Date%20ge%20datetime'"+year+"-06-01T00:00:00.000Z')%20and%20(Col_Date%20le%20datetime'"+year+"-12-31T00:00:00.000Z')",    
            type: "GET", dataType: "json", headers: {"accept": "application/json;odata=verbose"},    
            success: mySuccHandler, error: myErrHandler}); 
    }

    function mySuccHandler(a) {
        results = a.d.results;
        if (allResults.length > 0)
            allResults = allResults.concat(results);
        else
            allResults = results;        
    }
    function myErrHandler(data, errorCode, errorMessage) {
        console.log("Could not complete call: " + errorMessage);        
    };

   $.when(yearh1, yearh2).done(function(a1, a2){
      // console.log(allResults);
    $('#table_id').DataTable({
        data:allResults,
        dom: 'Bfrtip',
        columns: [
                    { data: "Title" },
                    { data: "Reg_x0020_No" },
        ]
    });
   });  
};

附录

在阅读了一些答案后,我添加了一个var allRequests. 现在,这允许我存储所有 API 调用的结果,但不会连接结果并将其传递给数据表以进行表渲染。

var results;
var allResults = [];
var allRequests = [];
$(document).ready(function () {
    load();
});

function load() {
for (let year = 2016; year < 2022; year++) {
    var yearh1 = $.ajax({    
        url: "SPO_Site/_api/web/lists/getbytitle('List_Name')/items?$top=5000&$select=*&$filter=(Incident_x0020_Date%20ge%20datetime%27"+(year-1)+"-12-31T20:00:00.000Z%27)%20and%20(Incident_x0020_Date%20lt%20datetime%27"+year+"-06-01T00:00:00.000Z%27)",    
        type: "GET", dataType: "json", headers: {"accept": "application/json;odata=verbose"},    
        success: mySuccHandler, error: myErrHandler}); 
    var yearh2 = $.ajax({    
        url: "SPO_Site/_api/web/lists/getbytitle('List_Name')/items?$top=5000&$select=*&$filter=(Incident_x0020_Date%20ge%20datetime%27"+year+"-06-01T00:00:00.000Z%27)%20and%20(Incident_x0020_Date%20le%20datetime%27"+year+"-12-31T00:00:00.000Z%27)",    
        type: "GET", dataType: "json", headers: {"accept": "application/json;odata=verbose"},    
        success: mySuccHandler, error: myErrHandler}); 

       allRequests.push(yearh1);
       allRequests.push(yearh2); 
}       
    function mySuccHandler(a) {
        results = a.d.results;
        if (allResults.length > 0)
            allResults = allResults.concat(results);
        else
            allResults = results;
    }

    function myErrHandler(data, errorCode, errorMessage) {
        console.log("Could not complete call: " + errorMessage);        
    };

   $.when($, allRequests).done(function(a1, a2){
    $('#table_id').DataTable({
        data:allResults,
        dom: 'Bfrtip',
        columns:[
                    { data: "Title" },
                    { data: "Reg_x0020_No" }
                ]
    });
   });  
};

标签: javascriptjquerysharepoint-onlinerest

解决方案


循环在每次迭代中覆盖 和 的值yearh1yearh2这就是为什么$.when()调用将只处理最后两个请求的结果。

您可以将响应收集到一个数组中,而不是分配给yearh1and yearh2,然后将该数组传播到$.when().

另外,我建议不要使用处理程序,而仅在执行调用success时处理数据。$.when()

这是看起来的样子:

function load() {
    const promises = [];
    for (let year = 2016; year < 2022; year++) {
        promises.push($.ajax({
            url: "SPO_Site/_api/web/lists/getbytitle('List_Name')/items?$top=5000&$select=*&$filter=(Col_Date%20ge%20datetime'"+(year-1)+"-12-31T20:00:00.000Z')%20and%20(Col_Date%20lt%20datetime'"+year+"-06-01T00:00:00.000Z')",
            type: "GET", dataType: "json", headers: {"accept": "application/json;odata=verbose"}
        }), $.ajax({    
            url: "SPO_Site/_api/web/lists/getbytitle('List_Name')/items?$top=5000&$select=*&$filter=(Col_Date%20ge%20datetime'"+year+"-06-01T00:00:00.000Z')%20and%20(Col_Date%20le%20datetime'"+year+"-12-31T00:00:00.000Z')",   
            type: "GET", dataType: "json", headers: {"accept": "application/json;odata=verbose"}
        })); 
    }

    function myErrHandler(data, errorCode, errorMessage) {
        console.log("Could not complete call: " + errorMessage);        
    }

    $.when(...promises).then(function(...responses){
        const allResults = responses.map(x => x[0].d.results);
        console.log(allResults);
        $('#table_id').DataTable({
            data:allResults,
            dom: 'Bfrtip',
            columns: [
                { data: "Title" },
                { data: "Reg_x0020_No" },
            ]
        });
    }).catch(myErrHandler);  
}

最后,考虑使用原生 Web API 来处理 HTTP 请求和 Promises:fetch代替$.ajaxPromise.all代替$.when. 界面略有不同,但值得过渡到这些标准。


推荐阅读