延迟承诺:.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
})