我是 NodeJS/JS 的菜鸟,我对我的代码有疑问。
我正在编写一个函数来从 DynamoDB 表中获取元素,我的第一个版本是这样的
const params = {
tableName: process.env.dynamoname
};
const result = await scanItems(params);
// Define conditions for getting free queues
let i = 0;
//
for (i; i < result.items.length; ++i) {
const paramsCount = {
tableName: process.env.dynamodt,
data: {
idTimeSlot: result.items[i].id
},
filterExpression: '#idTimeSlot = :idTimeSlot',
};
const res = await countItems(paramsCount);
// Put available queues in items
if (res.Count < result.items[i].maxQueueSize) {
items.push(result.items[i].id);
}
}
return items;
} 一个非常简单的解决方案,带有一个简单的 for 循环,得到了我预期的结果
我的一位同事对我说“并行化for循环”,所以我用谷歌搜索了很多并且我已经实现了这个
const params = {
tableName: process.env.dynamoname
};
const result = await scanItems(params);
// Define conditions for getting free queues
const itemsPromises = result.items.map(async (item) => {
const paramsCount = {
tableName: process.env.dynamodt,
data: {
idTimeSlot: item.id
},
filterExpression: '#idTimeSlot = :idTimeSlot',
};
const res = await countItems(paramsCount);
if (res.Count < item.maxQueueSize) {
return item.id;
}
return null;
});
const items = await Promise.all(itemsPromises);
return items.filter(id => id !== null);
}
我使用 Promise.all() 来等待使用 map() 方法获得的所有 Promise 完成,并返回带有过滤条件的元素。结果与第一个版本相同,但我不明白两个版本之间的区别。
所以,我的问题是:
我希望我的问题和疑问都清楚,感谢您的帮助!
使用 Promise.all 更好,因为它执行并行请求。假设你有 50 个查询,那么 Promise.all 将执行 50 个并行查询,这会更快,而在普通的 for 循环中,它将一个接一个地执行查询。假设你的一个查询需要 1 秒,那么在正常的 for 循环中,总共需要 50 秒,尽管由于 Promise.all 发出并行请求,你可能会在 5 秒内得到结果。
通常我们不想在 for 循环中放置任何异步内容,因为这将是一个耗时的操作。
但是仍然有很多改进可以完成,因为你仍然是 for 循环中的异步调用之一
const res = await countItems(paramsCount);
,尝试将其放在外面。
问题是,我们将所有承诺结合在一起,然后执行 Promise.all 以获得并行结果,但是您在两个版本中都在做相同的事情,您的
itemsPromises
没有承诺,因为您已经在里面添加了 await
for 循环。您可以做的是生成一个 paramsCount
查询数组,并使用所有这些 paramsCount 数组在 dynamodb 中执行 Promise.all。