Javascript 批量并行HTTP请求,每个请求使用异步for循环
我正在尝试使用数组中的一组关键字批量运行对API的并行请求 我遇到的问题是,对于每个关键字,我需要使用不同的Javascript 批量并行HTTP请求,每个请求使用异步for循环,javascript,node.js,async-await,es6-promise,Javascript,Node.js,Async Await,Es6 Promise,我正在尝试使用数组中的一组关键字批量运行对API的并行请求 我遇到的问题是,对于每个关键字,我需要使用不同的page参数再次运行请求,运行次数与page变量中的数字相同 我不断得到无法读取未定义的属性“then”以返回chainNext函数 在没有for循环的情况下,批处理的并行请求非常有效,我正在努力将for循环合并到流程中 // Parallel requests in batches async function runBatches() { // The keywords to re
page
参数再次运行请求,运行次数与page
变量中的数字相同
我不断得到无法读取未定义的属性“then”以返回chainNext
函数
在没有for循环的情况下,批处理的并行请求非常有效,我正在努力将for循环合并到流程中
// Parallel requests in batches
async function runBatches() {
// The keywords to request with
const keywords = ['many keyword strings here...'];
// Set max concurrent requests
const concurrent = 5;
// Clone keywords array
const keywordsClone = keywords.slice()
// Array for future resolved promises for each batch
const promises = new Array(concurrent).fill(Promise.resolve());
// Async for loop
const asyncForEach = async (pages, callback) => {
for (let page = 1; page <= pages; page++) {
await callback(page);
}
};
// Number of pages to loop for
const pages = 2;
// Recursively run batches
const chainNext = (pro) => {
// Runs itself as long as there are entries left on the array
if (keywordsClone.length) {
// Store the first entry and conviently also remove it from the array
const keyword = keywordsClone.shift();
// Run 'the promise to be' request
return pro.then(async () => {
// ---> Here was my problem, I am declaring the constant before running the for loop
const promiseOperation = await asyncForEach(pages, async (page) => {
await request(keyword, page)
});
// ---> The recursive invocation should also be inside the for loop
return chainNext(promiseOperation);
});
}
return pro;
}
return await Promise.all(promises.map(chainNext));
}
// HTTP request
async function request(keyword, page) {
try {
// request API
const res = await apiservice(keyword, page);
// Send data to an outer async function to process the data
await append(res.data);
} catch (error) {
throw new Error(error)
}
}
runBatches()
//批处理并行请求
异步函数runBatches(){
//要请求的关键字
const keywords=['此处有许多关键字字符串…'];
//设置最大并发请求数
const concurrent=5;
//克隆关键字数组
const keywordsClone=keywords.slice()
//每个批次未来解决承诺的阵列
const promises=新数组(并发).fill(Promise.resolve());
//异步for循环
const asyncForEach=async(页面,回调)=>{
对于(第页=1;第页){
//只要阵列上还有条目,就可以自行运行
if(关键字克隆长度){
//存储第一个条目,并方便地将其从数组中删除
const keyword=keywordsClone.shift();
//运行“未来承诺”请求
返回pro.then(异步()=>{
//-->这是我的问题,我在运行for循环之前声明常量
const promiseOperation=等待asyncForEach(页面,异步(页面)=>{
等待请求(关键字,页面)
});
//-->递归调用也应该在for循环内
返回下一步(承诺操作);
});
}
return-pro;
}
return wait Promise.all(promises.map(chainNext));
}
//HTTP请求
异步函数请求(关键字,页面){
试一试{
//请求API
const res=等待apiservice(关键字,页面);
//将数据发送到外部异步函数以处理数据
等待追加(res.data);
}捕获(错误){
抛出新错误(错误)
}
}
runBatches()
问题在于pro没有定义,因为您还没有初始化它
您基本上执行以下代码:
Promise.all(new Array(concurrent).fill(Promise.resolve().map(pro => {
// pro is undefined here because the Promise.resolve had no parameter
return pro.then(async () => {})
}));
我不完全确定你的想法,但这是你在更精简的版本中的问题。我通过将实际请求promiseOperation
移动到for循环中,并在那里返回递归函数,使其正常工作
// Recursively run batches
const chainNext = async (pro) => {
if (keywordsClone.length) {
const keyword = keywordsClone.shift()
return pro.then(async () => {
await asyncForEach(pages, (page) => {
const promiseOperation = request(keyword, page)
return chainNext(promiseOperation)
})
})
}
return pro
}
批处理中的并行请求的功劳归于它在开始时是未定义的,我从那里获取了批处理代码,它也表示未定义,但随后它们被填充,所有工作正常