首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用request-promise限制Node.js接口请求

使用request-promise限制Node.js接口请求
EN

Stack Overflow用户
提问于 2016-06-27 16:10:02
回答 2查看 3.7K关注 0票数 2

我正在尝试从我的node.js应用程序访问REST API端点,如下所示:

代码语言:javascript
复制
var people = [];
for(var i=0; i<n; i++) {
    //create person
    people.push(person);
}
return Promise.all(people.map(create3APIRequestPromises));

其中,create3APIRequestPromises大致如下:

代码语言:javascript
复制
// APIRequestPromise = require('request-promise')(options);
return Promise.all([APIRequestPromise1, APIRequestPromise2, APIRequestPromise3]);

对于少数人来说,代码都可以正常工作,但是如果我增加太多,它就会开始失败。我相信这个失败是因为提供REST API的服务限制了我的使用。因此,我的问题是,将我发送的请求数量限制在每秒10个请求的最佳方式是什么。

我读过有关node-rate-limiter的文章,但我看不出它如何与我在上面使用“request-promise”编写的承诺相匹配(可能这个模块不可能实现,所以也许你可以建议一个替代方案)。

谢谢。

EN

回答 2

Stack Overflow用户

发布于 2016-07-16 19:09:49

我认为在你的情况下,在发出请求之间使用简单的时间填充更好。要做到这一点,您应该将请求拆分成系列,并在每个组前添加延迟。我意识到example。用法为:

代码语言:javascript
复制
// Create timepad function
let timePad = createTimePad(5, 10e3); // 5 requests each 10 seconds

// Iterate over people
return Promise.all(
  people.map(
    (human) => timePad().then(() => create3APIRequestPromises(human))
  )
);

创建时间板的函数:

代码语言:javascript
复制
// Create timepad function where timeout is timeout between calls and series is the maximum
// number of calls that will be done simultaneously
function createTimePad(series = 10, timeout = 1000) {
  let seriesCounter = series;
  let delay = timeout;

  return () => {
    return new Promise((resolve) => {
      if (seriesCounter < 1) {
        delay += timeout;
        seriesCounter = series;
      }

      setTimeout(resolve, delay);

      seriesCounter -= 1;
    });
  };
}

它非常简单,可以根据自己的意愿将请求分成不同大小的组。

票数 2
EN

Stack Overflow用户

发布于 2016-07-16 15:55:04

嗯,这真是个好问题。我遇到了同样的问题,意识到还没有人解决这个问题,于是开始实现quota。它已经涵盖了你的用例。

如下所示创建您的经理:

代码语言:javascript
复制
var quota = require('quota');

var manager = new quota.Manager({
    backoff: 'timeout'
});

// 10 new requests per second
manager.addRule({
    name: 'main',
    limit: 10,
    window: 1000,
    throttling: 'window-sliding',
    queueing: 'fifo',
    resource: 'requests'
});

var quotaServer = new quota.Server();
quotaServer.addManager('custom', manager);

var quotaClient = new quota.Client(quotaServer);

然后通过这个包装器调用您的每个请求:

代码语言:javascript
复制
var request = require('request-promise');

function requestThrottled(options) {

    var _grant;

    return quotaClient.requestQuota('custom', {}, { requests: 1 }, {
        maxWait: 60000 // Each request will be queued for 60 seconds and discarded if it didn't get a slot to be executed until then
    })
            .then(function (grant) {

                _grant = grant;

                return request(options);

            })
            .finally(function () {

                if (_grant) {
                    _grant.dismiss();
                }

            });

}

您可以像以前一样提出您的请求:

代码语言:javascript
复制
Promise.all([
    requestThrottled(optionsRequest1),
    requestThrottled(optionsRequest2),
    requestThrottled(optionsRequest3)
])
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38048829

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档