这是来自Throttling requests to 3rd part Apis with Node的扩展问题。如果您想查看子功能以及我想要做的事情的一些背景故事,您可以在该帖子中看到我的完整代码。
我需要做的是将api请求延迟到api。我每秒钟达到服务器最大值。我试图使用Promise.delay但它似乎没有任何东西。这就是我如何使用它。
function getAllRegions(req, res){
getAllRegionsHrefs().then(function (hrefs){
var chunks = _.chunk(hrefs, 25);
return Promise.map(chunks, function(chunk) {
return Promise.map(chunk, getRegion).then(function (getRegionResults){
for(var item in getRegionResults) {
Promise.map(getRegionResults[item].constellations, getConstellationInfo).then(function (constellationInfo) {
var chunks = _.chunk(constellationInfo, 150);
return Promise.map(chunks, function (chunk) {
return Promise.map(chunk, getSystem).delay(20000);
})
}).delay(20000);
}
}).delay(200000);
});
});
}
现在这将只产生大约9k api请求,并且它构建了一个基于区域,星座和系统的宇宙。是否有更好的方法来限制嵌套请求?在每个嵌套中,调用次数呈指数上升。
似乎还不想等待。我是否再次陷入困境?我在那里添加了另外一个流程所需的功能。此外,分块似乎包裹了一个双阵列,所以我把它拿出来了。
function getAllRegions(req, res) {
getAllRegionsHrefs().then(function (hrefs) {
return Promise.mapSeries(hrefs, function (href) {
getRegion(href).then(function (regions) {
return Promise.mapSeries(regions.constellations, function (constellation) {
getConstellationInfo(constellation).then(function (constellationInfo) {
return Promise.map(constellationInfo, getSystem).delay(15000);
});
});
});
});
});
}
Unhandled rejection RequestError: Error: connect ETIMEDOUT
答案 0 :(得分:1)
Promise.map
并行启动所有请求,因此您的代码运行如下:
但是所期望的行为应该是连续的:
每个请求块应该等待前一个块的延迟。
你可以通过链接承诺来实现这一目标:
startRequests(chunks[0])
.then(function() {
return startRequests(chunks[1])
}).then(function() {
return startRequests(chunks[2])
}) // ...
或使用mapSeries
function getAllRegions(req, res){
getAllRegionsHrefs().then(function(hrefs) {
return Promise.mapSeries(hrefs, function(href) {
getRegion(href).then(function(region) {
var chunks = _.chunk(region.constellations, 150);
return Promise.mapSeries(chunks, function (chunk) {
return Promise.map(chunk, getSystem).delay(10000);
});
});
});
});
}
只有最里面的请求被分块,其他请求一个接一个地启动。
编辑:正如Bergi所说,mapSeries
(以及其他承诺实用程序)需要返回结果承诺。第一个承诺也可以返回以处理错误或链接更多的承诺。
function getAllRegions(req, res){
return getAllRegionsHrefs().then(function(hrefs) {
//...
getAllRegions().then(systems => {
//next step
}).catch(err => {
//handle errors
})