当您不知道页数时,如何使用 Node.js 在 while 循环中向 API 发出多个分页 GET 请求?
Posted
技术标签:
【中文标题】当您不知道页数时,如何使用 Node.js 在 while 循环中向 API 发出多个分页 GET 请求?【英文标题】:How to make multiple paginated GET requests to an API in while loop with Node.js when you don't know the page count? 【发布时间】:2018-06-28 14:27:01 【问题描述】:我正在使用 REST JSON API,它无法查询页面或条目的总数。但是我需要在一个循环中向 API 发出多个请求,以便获取所有可用数据。
在搜索了许多 *** 问题后,我能找到的最接近的工作解决方案成功发出多个请求,但仍然需要您知道最后一页是什么:
这行得通:
const async = require("async");
const request = require("request");
let page = 1;
let last_page = 20;
let json;
async.whilst(function ()
// condition here
return page <= last_page
,
function (next)
request(`https://driftrock-dev-test-2.herokuapp.com/purchases?$page&per_page=20`, function (error, response, body)
if (!error && response.statusCode == 200)
json = JSON.parse(body);
console.log(json.data);
console.log(page);
page++;
next();
);
,
function (err)
// All things are done!
);
我试图稍微调整一下以适应我不知道最后一页(下)的要求,但我不知道如何正确地获取逻辑或如何解决获取json
的异步问题变量未定义。我需要获取 json.data 数组的值来确定包含来自 API 响应的所有对象数据的数据数组的长度。
这不起作用 - 返回undefined
:
const async = require("async");
const request = require("request");
let page = 1;
let json;
async.whilst(function ()
// condition here
json.data.length !== 0
,
function (next)
request(`https://driftrock-dev-test-2.herokuapp.com/purchases?$page&per_page=20`, function (error, response, body)
if (!error && response.statusCode == 200)
json = JSON.parse(body);
console.log(json.data);
console.log(page);
page++;
next();
);
,
function (err)
// All things are done!
);
我已经解决这个问题很长时间了,所以任何帮助都将不胜感激!谢谢!
【问题讨论】:
问题似乎是你无法获得一次调用 API 的结果,不是吗?更不用说最后一个了? 同时获取当前页面和page+1。如果 page+1 返回 0 个项目,则禁用下一个按钮。您不需要知道有多少项目 - 只需处理到达最后一页。 感谢@Archer,到目前为止,这似乎是最有用的提示,但你能发布完整的解决方案吗? 比如里面放的正确逻辑是什么:async.whilst(function () // condition here
我已经尝试过了。它至少应该为您指明正确的方向。我将有一天会开始使用 Node.js! :p
【参考方案1】:
正如我所说,我不是 Node.js 用户,因此不熟悉您正在使用的库,但这至少是一个普遍的想法......
function getPage(page)
request(`https://driftrock-dev-test-2.herokuapp.com/purchases?$page&per_page=20`, function (error, response, body)
if (!error && response.statusCode == 200)
// do whatever you do with the current page here.
if (json.data.length == 20)
request(`https://driftrock-dev-test-2.herokuapp.com/purchases?$page + 1&per_page=20`, function (error, response, body)
var json = JSON.parse(body);
if (json.data.length == 0)
// the next page has no items - disable the next button here
);
else
// this page has < 20 items - disable the next button here
);
您调用该方法,它将获取参数指定的页面,并检查它是否是最后一页并禁用下一个按钮(一旦您添加了执行该操作的代码)。
【讨论】:
感谢 Archer,这很有用,但我认为这里需要一些控制流逻辑,当 `json.data.length 为 0 时停止将页面迭代 1。您可以使用 runkit试试看。 (在需要时自动包含依赖项)根据您的示例在此处查看我的伪代码:runkit.com/daneasterman/5a61e0330fe2d50012b3941e【参考方案2】:您的逻辑存在一些问题。首先,您不会同时在测试函数中返回验证。但即使你这样做了,你也在测试一个未定义的变量。这样验证将在第一次迭代之前失败并退出您的代码。
let oldPage = 1;
let nextPage = 2;
let json;
async.whilst(function ()
// Check that oldPage is less than newPage
return oldPage < nextPage;
,
function (next)
request(`https://driftrock-dev-test-2.herokuapp.com/purchases?$oldPage&per_page=20`, function (error, response, body)
if (!error && response.statusCode == 200)
json = JSON.parse(body);
console.log(json.data);
console.log(oldPage);
if (json.data.length)
// When the json has no more data loaded, nextPage will stop
// incrementing hence become equal to oldPage and return
// false in the test function.
nextPage++;
oldPage++;
next();
);
,
function (err)
// All things are done!
);
这样您就可以看到没有新页面可显示的那一刻。
【讨论】:
谢谢,这行得通!我理解return
部分,但你能在评论中快速解释一下为什么条件 oldPage
我在 iteratee 函数中添加了注释。您正在验证 json 里面是否为空。当 json 为空时,nextPage 计数器停止增加,因此对于下一次迭代,oldPage 将等于 newPage。因此,测试函数中的条件将为 false 并停止运行 iteratee。以上是关于当您不知道页数时,如何使用 Node.js 在 while 循环中向 API 发出多个分页 GET 请求?的主要内容,如果未能解决你的问题,请参考以下文章
当您不知道 Swift 中的项目类型时,如何解码嵌套的 JSON 数据? [复制]
Angular 2:当您不知道 childComponent 的类时,如何将 childComponent 属性发送给 parent?