从多个API请求推送到全局数组

时间:2022-10-06 23:38:18

I have a function that calls a paginated API. It makes an initial call to the first page, then continues to make requests to the subsequent pages using the next url returned in the response. It does this until next is null. I am trying to extract data (city names) from the response and push these to a global array.

我有一个调用分页API的函数。它首先调用第一页,然后继续使用响应中返回的下一个URL向后续页面发出请求。它执行此操作直到next为null。我试图从响应中提取数据(城市名称)并将它们推送到全局数组。

My code currently looks like this:

我的代码目前看起来像这样:

var results = [];
function nextPage(url) {
    if (!url) {
        return;
    }
    $.getJSON(url, function(data) {
        nextPage(data.next);
        $.each(data.results, function (k, v) {
            results.push(v.city_name);
        });
    });
}

nextPage('http://url.com/api/v1/cities/?page=1');
console.log(results);

Assuming I have two pages of JSON that look like this:

假设我有两页JSON,如下所示:

Page 1

第1页

{
    "count": 105,
    "next": "http://url.com/api/v1/cities/?page=2",
    "previous": null,
    "results": [
        {
            "city_name": "Paris"
        },
        {
            "city_name": "Brussels"
        }
    ]
}

Page 2

第2页

{
    "count": 105,
    "next": null,
    "previous": "http://url.com/api/v1/cities/?page=1",
    "results": [
        {
            "city_name": "Manchester"
        },
        {
            "city_name": "Curitiba"
        }
    ]
}

I would expect the array to look like this:

我希望数组看起来像这样:

["Paris", "Brussels", "Manchester", "Curitiba"]

However, when I log results to the console the array is empty. Can anyone help? Let me know if you need any more information. Cheers

但是,当我将结果记录到控制台时,数组为空。有人可以帮忙吗?如果您需要更多信息,请与我们联系。干杯

2 个解决方案

#1


1  

Here's how I would suggest you do this using jQuery promises:

以下是我建议您使用jQuery承诺执行此操作的方法:

function getCities(initialUrl) {
    var results = [];

    function nextPage(url) {
        return $.ajax(url, {method: "POST", data: {json: src[cntr++]}}).then(function(data) {
            $.each(data.results, function (k, v) {
                results.push(v.city_name);
            });
            if (data.next) {
                return nextPage(data.next);
            } else {
                return results;
            }
        });
    }

    return nextPage(initialUrl);
}

getCities('http://url.com/api/v1/cities/?page=1').then(function(results) {
    console.log(results);
}, function(err) {
    // handle error here
});

This allows you to call then function and then get the data out of the function to use in other code. It also provides an error handling path.

这允许您调用then函数,然后从函数中获取数据以在其他代码中使用。它还提供错误处理路径。

The getCities function takes the first URL and then returns a promise that resolves with the array of results as it's fulfilled value.

getCities函数获取第一个URL,然后返回一个promise,该promise使用结果数组解析,因为它已满足值。

The internal nextPage() function takes the next URL. I tests the url it gets in the results and then either calls itself again on that url chaining the next promise to the original or returns the final result as the ultimate fulfilled value of the promise.

内部nextPage()函数接受下一个URL。我测试它在结果中获得的url,然后再次在该url上调用自己,将原始的下一个承诺链接起来,或者将最终结果作为promise的最终履行值返回。

#2


1  

Like mentioned in the comments, console.log is executed before the requests are completed. Instead you would want to do something like this:

如评论中所述,console.log在请求完成之前执行。相反,你会想做这样的事情:

var results = [];
function nextPage(url) {
    if (!url) {
        return;
    }
    $.getJSON(url, function(data) {
        $.each(data.results, function (k, v) {
            results.push(v.city_name);
        });
        if(data.next){
            // There is a next page, continue:
            nextPage(data.next);
        }else{
            // You're done:
            console.log(results);
        }
    });
}

nextPage('http://url.com/api/v1/cities/?page=1');

#1


1  

Here's how I would suggest you do this using jQuery promises:

以下是我建议您使用jQuery承诺执行此操作的方法:

function getCities(initialUrl) {
    var results = [];

    function nextPage(url) {
        return $.ajax(url, {method: "POST", data: {json: src[cntr++]}}).then(function(data) {
            $.each(data.results, function (k, v) {
                results.push(v.city_name);
            });
            if (data.next) {
                return nextPage(data.next);
            } else {
                return results;
            }
        });
    }

    return nextPage(initialUrl);
}

getCities('http://url.com/api/v1/cities/?page=1').then(function(results) {
    console.log(results);
}, function(err) {
    // handle error here
});

This allows you to call then function and then get the data out of the function to use in other code. It also provides an error handling path.

这允许您调用then函数,然后从函数中获取数据以在其他代码中使用。它还提供错误处理路径。

The getCities function takes the first URL and then returns a promise that resolves with the array of results as it's fulfilled value.

getCities函数获取第一个URL,然后返回一个promise,该promise使用结果数组解析,因为它已满足值。

The internal nextPage() function takes the next URL. I tests the url it gets in the results and then either calls itself again on that url chaining the next promise to the original or returns the final result as the ultimate fulfilled value of the promise.

内部nextPage()函数接受下一个URL。我测试它在结果中获得的url,然后再次在该url上调用自己,将原始的下一个承诺链接起来,或者将最终结果作为promise的最终履行值返回。

#2


1  

Like mentioned in the comments, console.log is executed before the requests are completed. Instead you would want to do something like this:

如评论中所述,console.log在请求完成之前执行。相反,你会想做这样的事情:

var results = [];
function nextPage(url) {
    if (!url) {
        return;
    }
    $.getJSON(url, function(data) {
        $.each(data.results, function (k, v) {
            results.push(v.city_name);
        });
        if(data.next){
            // There is a next page, continue:
            nextPage(data.next);
        }else{
            // You're done:
            console.log(results);
        }
    });
}

nextPage('http://url.com/api/v1/cities/?page=1');