我正在尝试使用 Promise 并行化我的数据库查询。 假设我需要进行 35000+ 数据库查询,并且我尝试使用 Promise.all([iterables]) 来实现它。我面临的问题是,创建可迭代的循环花费了太长的时间(大约 25 秒),而等待 Promise 解析只花费了 15 秒。 我不明白为什么 for 循环要花这么长时间,根据我的理解,它只是附加到承诺数组并使承诺处于挂起状态。 附言。我使用的是 aws lambda 函数,内存为 1GB,超时为 1 分钟。
这是我的示例代码:
const querymetadata = async() => {
let result = [],
lastEvaluatedKey = null;
const getQuery = {
TableName,
KeyConditionExpression: "device_id = :device_id",
ExpressionAttributeValues: {
":device_id": "EK431",
}
};
do {
const { Items, LastEvaluatedKey } = await docClient
.query({ ...getQuery, ExclusiveStartKey: lastEvaluatedKey })
.promise();
result = result.concat(Items);
lastEvaluatedKey = LastEvaluatedKey;
} while (lastEvaluatedKey);
console.log(result.length);
return result.length;
}
exports.handler = async (event, context) => {
console.log('start');
for(let i = 0; i < 35000; i++) {
promises.push(querymetadata());
}
console.log('end');
await Promise.all(promises);
console.log('end lambda');
}
在上面的代码中,从开始到结束控制台所需的时间是 25 秒
我已经在 aws lambda 函数中尝试了上述代码。我不明白为什么要花这么长时间才能创建承诺迭代
使用您的代码,所有承诺都会同时排队,然后当您调用“等待”时它们就会开始。 最好创建某种队列。
这是一个非常基本的示例,它并行执行 3 个操作并等待包括所有内容在内的最终结果:
function op(id) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(`ok ${id}`)
}, 1000)
})
}
const MAX_CONCURRENT = 3
let pendingCount = 0
const results = []
function runNextOp(finalResolve) {
if ((pendingCount < MAX_CONCURRENT) && (actionsParam.length > 0)) {
const p = actionsParam.shift()
op(p).then((res) => {
results.push([p, res])
pendingCount -= 1
runNextOp(finalResolve)
if ((pendingCount === 0) && (actionsParam.length === 0)) {
finalResolve(results)
}
})
pendingCount += 1
}
}
const actionsParam = [1, 2, 3, 4, 5]
function allOps() {
return new Promise((finalResolve) => {
for (let i = 0; i < MAX_CONCURRENT; i += 1) {
runNextOp(finalResolve)
}
})
}
(async () => {
const allResult = await allOps()
console.log(allResult)
})()