我有大量的请求,我需要同时运行大约200到600个上述请求,但不超过该数量。目前,我正在同时发送40万个请求,但是它会咀嚼我的堆内存,然后跳转到它-也就是说,它使用了多个GB的内存,而我没有。
我目前正在使用类似于此的循环来处理请求:
["url1", "url2", ...].forEach(async item => {
Axios(config)
.then(res => DO STUFF)
.catch(err => console.log(err);
await DO_MORE STUFF
});
链接实际上存储在MongoDB集合中,我正在使用Cursor.forEach。
答案 0 :(得分:3)
您可以使用光标的nextObject
功能。
这里是使用它的解决方案(未经测试,可能存在语法错误)
let axiosConfigs = [];
async function runAxios() {
// Do your axios stuff here on axiosConfigs
// Here is an example :
await Promise.all(axiosConfigs.map((config) => {
return Axios(config);
}))
// Once finished, clear the axiosConfigs array
axiosConfigs = [];
}
function createAxiosConfig(urlRecord) {
// return here the axios config for this url record
}
const cursor = db.collection("urls").find({});
while(await cursor.hasNext()) {
const urlRecord= await cursor.next();
axiosConfigs.push(createAxiosConfig(urlRecord));
if(axiosConfigs.length === 200) {
await runAllAxioses()
}
}
与此相关,您将有200个axios请求的批次。一旦所有200个axios查询结束,就开始构建下一个批次
答案 1 :(得分:1)
因此,您必须将阵列切成较小的阵列,并为每个切片循环循环,并增加超时时间。
let urls = ["url1", "url2", ...];
let reqPerTime = 400;
let rampUp = 0 ;
function loopRecursively (from ) {
if ( from > urls.length ) { return ;}
let arr = urls.slice(from, from + reqPerTime );
arr.forEach(async item => {
Axios(config)
.then(res => DO STUFF)
.catch(err => console.log(err);
await DO_MORE STUFF
});
rampUp = rampUp + 500;
setTimeout ( () => { loopRecursively( from + reqPerTime ) }, rampUp );
}
loopRecursively(0);
答案 2 :(得分:-1)
在异步功能中,需要使用await进行停止循环,直到执行操作为止。 您的确做到了,但是循环还返回了要解决以获得正确结果所需的promise数组
const urls = ["url1", "url2", ...]
const allPromise = urls.map(async item => {
try {
const res = await Axios(config)
await DO_MORE STUFF
} catch(error) {
console.log({ error })
}
});
await Promise.all(allPromise)
如果外部函数不是异步函数,则可以使用.then