创建可迭代的 Promise 需要更长的时间

问题描述 投票:0回答:1

我正在尝试使用 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 函数中尝试了上述代码。我不明白为什么要花这么长时间才能创建承诺迭代

javascript node.js concurrency promise
1个回答
0
投票

使用您的代码,所有承诺都会同时排队,然后当您调用“等待”时它们就会开始。 最好创建某种队列。

这是一个非常基本的示例,它并行执行 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)
})()

© www.soinside.com 2019 - 2024. All rights reserved.