我有一个用Node编写的服务,它将请求发送到另一个API服务,以获取特定城市的团队列表。
请求参数:
city
page
per_page
响应体:
page
per_page
more
teams
默认情况下,per_page
设置为1000,但团队的数量远远大于1000,并且一些团队不会在响应中返回。我需要所有的团队。出于某些原因,我不打算在这里指定,我不想更改per_page
参数,但我想要做的是发送第一个请求并检查响应体中的more
是否为true
(意味着有更多的团队),我从响应体中提取团队并将其添加到最终结果中,增加page
参数并发送带有参数的请求:
{
"page": "2",
"city": "chicago",
"per_page": 1000,
}
我一直这样做,直到more
报头为false
。
该服务是用Node编写的,我使用request
包来发送HTTP请求。最初,我想使用while loop
function teamsInCity(city, page, result, callback) {
let more = true;
while(more) {
// send the request
// extract teams into the result array
// check if there is more
// send another request
// keep sending requests and appending teams until more is false
}
// return the final result with all the teams
}
但这并不起作用,因为while loop
发送请求并继续执行下一行代码,而不等待响应。所以我用递归解决了它,它起作用了。但我需要它是尾部调用优化的,我不确定,但我认为Node不支持这一点,但我可能错了。
有没有一种方法可以在不使用async/await
和promises的情况下在while loop
内部发送请求?
下面是我的递归工作函数:
function teamsInCity(city, page, result, callback) {
request.get({
url: 'my_service' + '/teams',
qs: { 'city' : city, 'page': page, 'per_page': 1000 },
json: true
}, function(err, response, body) {
if (err) { return callback(err); }
result = result.concat(body.teams);
if (body.more) {
page++;
return teamsInCity(city, page, result, callback);
}
return callback(null, result);
});
}
下面是调用teamsInCity()
的路由
router.get('/:city', function(req, res) {
var data = {teams: []};
myService.teamsInCity(req.params.city, 1, [], function(err, teams) {
if (err) {
logger.error('Error while retrieving teams in ' + req.params.city);
}
data.teams = _.sortBy(teams, 'name');
res.send(data);
});
});
谢谢!
发布于 2019-07-15 15:32:29
您可以使用async库和whilst函数。我不认为这会使你的堆栈溢出;-)
例如:
const async = require("async");
function teamsInCity(city, callback) {
let result = [];
let page = 0;
let more = true;
async.whilst(
() => more,
(callback2) => {
request.get({
url: 'my_service' + '/teams',
qs: { 'city' : city, 'page': page++, 'per_page': 1000 },
json: true
}, (err, response, body) => {
if (err) {
callback2(err);
console.error(`teamsInCity: Error occurred: ${err.message}`);
} else {
console.log(`teamsInCity: Page#: ${page}, Team count: ${body.teams.length}, More pages: ${body.more}`);
more = body.more;
result = result.concat(body.teams);
callback2(null, result);
}
})
},
(err, result) => {
if (err) console.error("Final callback error: ", err.message);
if (!err) console.log("Final callback result: ", result);
callback(err, result);
}
);
}
https://stackoverflow.com/questions/57033775
复制相似问题