Async + Axios - 速率控制

时间:2017-08-14 14:01:03

标签: node.js asynchronous axios

我目前正在使用promises 200次向API发送GET请求。毫不奇怪,在如此短的时间内允许最大数量的连接。

我正在使用axios来执行此操作:

const memberPromises = members.map(member => axios.get(`players/%23${member.tag}`))

axios.all().then().catch() // etc

..成员最多可以有200个元素。

似乎没有办法在axios内本地对这些请求进行速率控制,但我如何使用async(或者如果有更好的话,则使用其他库) queue参数的concurrent方法可以限制同时发出的请求数量?

2 个答案:

答案 0 :(得分:4)

这个怎么样?

将成员映射到promises,在超时后解析promise

let RATE_LIMIT_BASE = 100; //100ms separation

let promises = members.map((member, idx) => {
    return new Promise((resolve, reject) => {
        setTimeout(
            () =>
                axios
                    .get(`players/%23${member.tag}`)
                    .then(res => resolve(res))
                    .catch(err => reject(err)),
            RATE_LIMIT_BASE * idx
        );
    });
});

Promise.all(promises).then().catch(); // etc;

评论中,正如marvel308所说,

  

在某些情况下可能会失败,因为setTimeout只是保证   调用setTimeout后代码将至少执行100ms,   如果有些CPU,它们仍然可以在事件队列中排队   密集型任务阻止了调用堆栈

感谢marvel308的建议

答案 1 :(得分:0)

const axios = require('axios');
const axiosThrottle = require('axios-throttle'); 
//pass axios object and value of the delay between requests in ms
axiosThrottle.init(axios,200)
const options = {
  method: 'GET',
};
const promises = [];
const responseInterceptor = response => {
  console.log(response.data);
  return response;
};

//add interceptor to work with each response seperately when it is resolved
axios.interceptors.response.use(responseInterceptor, error => {
  return Promise.reject(error);
});

for (let index = 0; index < members.length; index++) {
  options.url = `http://yourapiurl/players/%23${member.tag}`;
  promises.push(axiosThrottle.getRequestPromise(options, index));
}

//run when all promises are resolved
axios.all(promises).then(responses => {
  console.log(responses.length);
});

https://github.com/arekgotfryd/axios-throttle