本文介绍了如何制作它以便我可以在javascript中一次执行说10个承诺以防止api调用的速率限制?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有1000条记录需要访问速率受限的API端点。我想这样做,以便在任何给定时间只有5次调用URL,这样我就不会同时发出1000个请求。我怎样才能做到这一点?我有以下内容:

I have 1000 records that need to hit an API endpoint that is rate limited. I want to make it so that there is only 5 calls on the URL at any given time so that I am not making 1000 requests simultaneously. How can I do this? I have the following:

var Promise = require("bluebird");
var geocoder = Promise.promisifyAll(require('geocoder'));
var fs = require('fs');
var async = require('async');
var parse = require('csv-parse/lib/sync');
var inputFile = './myaddresses.txt'
var file = fs.readFileSync(inputFile, "utf8");

var records = parse(file, {columns: true});
var promises = [];
for(var i = 0; i < records.length; i++) {
    var placeName = records[i]['Place Name'];
            promises.push(geocoder.geocodeAsync(placeName));    
}

Promises.all(promises).then(function(result) {
  result.forEach(function(geocodeResponse) {
  console.log(geocodeResponse);
  })
}


推荐答案

要限制一次传入的并发请求数,我建议使用Bluebird的 Promise.map(),它提供并发选项。它将完成所有操作以下内容适用于您:

To limit the number of concurrent requests that are in-flight at once, I'd recommend using Bluebird's Promise.map() which offers a concurrency option. It will do all of the following for you:


  1. 迭代您的数组

  2. 限制并发请求的数量您将并发选项设置为

  3. 在最终结果数组中按顺序收集所有结果

以下是如何使用它:

const Promise = require('bluebird');

Promise.map(records, r => {
    let placeName = r['Place Name'];
    return geocoder.geocodeAsync(placeName));
}, {concurrency: 5}).then(results => {
    // all results here
}).catch(err => {
    // process error here
});

注意:速率限制通常与并发请求的数量通常不完全相同。限制并发请求的数量将使您更有可能保持在速率限制之下,但不会保证。有特定的速率限制模块可以更直接地管理速率限制。

Note: Rate limiting is not usually strictly the same as number of concurrent requests. Limiting the number of concurrent requests will make it more likely that you stay under a rate limit, but won't guarantee it. There are specific rate limiting modules that can manage to a rate limit more directly.

您可以为每个请求添加延迟使用Bluebird的 .delay()

You can add a delay to each request using Bluebird's .delay().

const Promise = require('bluebird');

Promise.map(records, r => {
    let placeName = r['Place Name'];
    return geocoder.geocodeAsync(placeName)).delay(500);
}, {concurrency: 5}).then(results => {
    // all results here
}).catch(err => {
    // process error here
});






处理某些类型费率的经典算法限制称为。

如果你的限制是50个请求/秒,那么你可以确保你的并发数乘以你的延迟值永远不会超过50 /秒。

If your limit is 50 requests/sec, then you can just make sure that your concurrency number times your delay value never allows more than 50/sec.

这篇关于如何制作它以便我可以在javascript中一次执行说10个承诺以防止api调用的速率限制?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-27 17:35