延迟承诺:.delay() 似乎不起作用
Delaying promises: .delay() doesn't seem to work
这是 的扩展问题。如果您想查看子函数和我正在尝试做的事情的一些背景故事,您可以在 post 中查看我的完整代码。
我需要做的是延迟 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 个请求,它会构建一个基于区域、星座和系统的宇宙。有没有更好的方法来限制嵌套请求?在每个嵌套中,调用次数呈指数增长。
更新
似乎还是不想等。我是不是又把嵌套搞砸了?我在其中添加了流程所需的 1 个功能。此外,分块似乎包裹了一个双数组,所以我把它拿出来了。
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
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
})
这是
我需要做的是延迟 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 个请求,它会构建一个基于区域、星座和系统的宇宙。有没有更好的方法来限制嵌套请求?在每个嵌套中,调用次数呈指数增长。
更新
似乎还是不想等。我是不是又把嵌套搞砸了?我在其中添加了流程所需的 1 个功能。此外,分块似乎包裹了一个双数组,所以我把它拿出来了。
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
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
})