如何从API响应中的多个页面获取结果?

时间:2019-07-09 18:49:00

标签: javascript node.js

我想对所有ChartMogul Customer.All()API调用的所有结果进行分页。我正在使用Chartmogul NPM package

它可以工作,我可以获得所有结果,但是我得到的结果比单个调用中允许的最大记录数还多,因此我需要分页浏览多页结果。而且我迷上了如何优雅地做到这一点。

我可以进行多个调用,首先获取页面总数,然后循环遍历所有页面。将所有结果保存在一个大对象中。

这是调用,cont变量应更新到x页。

DECLARE @CSV VARCHAR(MAX) 
DECLARE @CSV1 VARCHAR(MAX) 
SELECT @CSV = COALESCE(@CSV + ', ', '') + CONVERT(varchar(10), Coefficient) from Temp 
SELECT @CSV = '['+@CSV +']'
SELECT @CSV1= (SELECT @CSV AS Result For JSON PATH, WITHOUT_ARRAY_WRAPPER) 
SELECT REPLACE (REPLACE(@CSV1,'"[','['),']"',']');

chartmogul的每个API响应均包含以下详细信息

page

那么我如何以一种简单,优雅的方式遍历响应的所有页面?

2 个答案:

答案 0 :(得分:3)

这种模式应该可以让您顺利前进。

使用一个返回主要诺言的函数,当返回更多诺言时,您将对该函数的递归调用(另一个诺言)或返回合并结果。

以下未经测试,并且从未使用过此API可能需要进行一些调整。

function getEntries(config, page=0, entries = []) {
  // return promise
  return ChartMogul.Customer.all(config, {
    status: 'Active',
    per_page: 200,
    page: page
  }).then(res => {
    // merge into main array
    entries = [...entries, ...res.entries];
    // return another promise if there are more ... or return the combined array
    return res.has_more ? getEntries(config, res.page+1, entries) : entries;
  });

}

getEntries(config)
    .then(entries => console.log(entries) )
    .catch(err => console.error(err) )

答案 1 :(得分:0)

像charlietfl我建议您使用诺言。区别在于,我将同时启动所有请求,然后等待所有请求完成。

取决于获取此方法所需的页面数,速度更快,但是如果您需要的40 requests/second以上,它可能会发送太多请求

仅当您事先知道有多少页时才能执行此操作。

(由于我没有api密钥,因此未经过测试)

// start a promise for every page given
function startRequests(pages) {
    return pages.map((page) => ChartMogul.Customer.all(config, {
        status: 'Active',
        per_page: 200,
        page: page
    }))
}

// an array of all the pages you want to get from the server.
// the function below could be used to generate the page numbers
// Array.from({length: numberOfPages}, (x,i) => i + 1);
let pages = [1,2,3,4] 

let requestPromises = startRequests(pages)

// wait for the promises to finish
Promise.all(requestPromises)
.then(function(results) {
    // combine all the results into a single array
    return results.reduce((combinedResults, result) => [...combinedResults, result.entries], [])
}).then((combinedResults) => {
    // do whatever is needed
}).catch(err => console.error(err));