使用async.js发出并行POST请求,并在给定时间将请求数限制为3

时间:2016-06-22 19:56:18

标签: javascript node.js post asynchronous request

我需要发出并发POST请求才能从服务器获取数据,但是在给定时间内要进行的并发请求数应为5,一旦完成,则接下来的5个请求可以触发,然后它应该继续直到达到上限。

为了做到这一点,我试图使用异步,因为我的节点应用程序,我需要它在我的JS模块中的npm安装后。我想知道我是否可以使用async.parallelLimit(或)async.eachLimit来满足此要求。在他们两个看起来我们可以提到限制。我在这里引用一个很好的例子http://www.devblogrbmz.com/playing-around-with-async-js/来使用eachLimit。

我使用“request”模块向服务器发送POST请求。从根本上说,最终场景是,当提供startDate和endDate时,我需要获得包括开始和结束在内的天数,然后我需要为每个日期发出POST请求以从服务器获取数据。在对每个日期发出请求时,使用异步限制参数我需要将其限制为5,因此在给定的时间点只会发出5个POST请求,然后接下来的5个将在此之后开始,并且它会一直持续到上限。

任何人都可以建议我可以使用哪个异步。 parallelLimit还是eachLimit?

以下是代码使用forEachLimit的方式,

var diffDays = ['2016-05-31', '2016-06-01', '2016-06-02', '2016-06-03', '2016-06-04', '2016-06-05', '2016-06-06']

async.forEachOfLimit(diffDays, 3, function (value, key, callback) {
    console.log(value + " @forEach");
    makeRequest(value),
    callback();
}, function (error, results) {
    if(error) {
        console.log('An error occured ' + error);
    }
});

makeRequest是我正在执行POST请求操作的地方

function makeRequest (days) {
request({
    url     : "/api/retrieveEndPoint",
    method  : "POST",
    headers : options,
    json    : {
                "path": days
              }
    }, function(error, response, body) {
      if(body) {
        console.log(days + " @makeRequest");
      }
      else if (error) {
        console.log('An error occured ' + error);
      }
})};

所以基本上如果我看到带有@forEach的console.log,它将于2016年5月31日至2016年6月6日打印。另一方面,如果我看到带有@makeRequest的console.log,它会以随机顺序打印日期,因为它执行请求。我想保持相同的顺序,并且它应该在给定的时间点提出3个请求。

2 个答案:

答案 0 :(得分:0)

您应该选择哪种方式更适合您的方案,以及是否需要一个接一个地执行请求。基本上我认为使用parallelLimit应该没问题,因为所有请求都不依赖于彼此,而是更多地关于流控制和执行某些任务,而不是以异步方式迭代集合。

答案 1 :(得分:0)

如果没有一些工作,你将无法维持秩序并获得并行处理的好处。 async.forEachOfLimit应按顺序发送请求,但您无法保证它们将按顺序返回。如果您正在做一些依赖于按顺序收集结果的事情,那么您可以使用索引:

var diffDays = ['2016-05-31', '2016-06-01', '2016-06-02', '2016-06-03', '2016-06-04', '2016-06-05', '2016-06-06'];
var diffResults = new Array(diffDays.length);

async.forEachOfLimit(diffDays, 3, function (value, key, callback) {
    console.log(value + " @forEach");
    makeRequest(value diffResults, key);
    ...
}, function(err){ //<-- there is no second argument in async.forEachOfLimit
  diffResults.forEach... // assuming no error process in order results
});

然后请求成为:

function makeRequest (days, resultBuf, resultIndex) {
request({
    url     : "/api/retrieveEndPoint",
    method  : "POST",
    headers : options,
    json    : {
                "path": days
              }
    }, function(error, response, body) {
      if(body) {
        console.log(days + " @makeRequest");
        resultBuf[resultIdx] = body; //in order results collected

      }
      else if (error) {
        console.log('An error occured ' + error);
      }
})};