我的网址列表非常多,我需要使用这些网址调用多个外部REST API端点,以获取其余数据。然后将这些数据插入数据库。
以下是从REST API获取数据并将结果存储到数据库中的代码片段:
// Opening storage model
await storageModel.open();
// Iterate through all the links
for (let idx = 0; idx < links.length; idx++)
{
console.log("Checking link %j of %j", idx+1, links.length);
link = links[idx];
// Getting link data (slow)
try {
let data = await checkLinkAndGetData(linkGetter, link);
await storageModel.insert(data);
}
catch (error) {
// Processing some errors
...
}
}
await storageModel.close();
该代码的性能非常差,因为它在继续下一个链接之前会等待Promises解析。我想要的是“排队” 5-10个异步调用(无需等待它们),并使循环仅在某些“排队”的承诺得到解决时才继续进行下一个链接。
附言我使用的是本地Promises,而不是Bluebird。
最佳答案
一种选择是一次创建5-10个承诺,将它们存储在一个数组中,然后await
ing Promise.all(promises)
。例如:
// Opening storage model
await storageModel.open();
// Iterate through all the links
for (let block = 0; block < links.length; block += 10)
{
const promises = [];
// Collect promises in blocks of 10.
for (let idx = block; idx < links.length && idx < block + 10; idx++)
{
console.log("Checking link %j of %j", idx+1, links.length);
link = links[idx];
promises.push(checkLinkAndGetData(linkGetter, link));
}
try {
// Wait for all 10 promises to finish (in any order).
let data = await Promise.all(promises);
// Still await each insert so that the ordering is maintained.
for (let idx = 0; idx < data.length; idx++)
{
await storageModel.insert(data);
}
}
catch (error) {
// Processing some errors
...
}
}
await storageModel.close();
关于javascript - 在循环中同时排队异步请求,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56156225/