【问题标题】:forEach not running inside lambda functionforEach 不在 lambda 函数内运行
【发布时间】:2020-02-13 01:03:29
【问题描述】:

我有一个 Node.js AWS Lamba 函数,它执行 DB 调用,然后将 DB 调用的结果拆分为不同的 SQS 消息。目前,由于 Lambda 跳过了所有内容,并且当我添加 await(如下所示)时,它告诉我不能将 await 用于 sendMessage 部分。

module.exports.companyID = async (event, context, callback) => {
    context.callbackWaitsForEmptyEventLoop = false;
    if (inter_conn == null) {
        inter_conn = await mongoose.createConnection(incident_Mongo_URI, {
            bufferCommands: false, // Disable mongoose buffering
            bufferMaxEntries: 0, // and MongoDB driver buffering
            useNewUrlParser: true // Required or it gives me an error
        });
    }

    const I = inter_conn.model('Incident');
    await I.find().distinct('companyID').exec(function(err, results) {
        if(err) {
            logger.error(`Inter Cleanup: Find: Error message: ${JSON.stringify(err)}`);
            process.exit(1);
        }
        logger.info(results)
        results.forEach(companyID => {
            let params = {
                MessageBody: companyID,
                QueueUrl: process.env.incidentsQueue,
                DelaySeconds: 0
            };

            let sendMessage = sqs.sendMessage(params).promise();

            await sendMessage.then((data) => {
                logger.info(data)
            })
            .catch((err) => {
                logger.error(err)
            })
        }); 
    })

    let output = {
        status: 'Done'
    }
    callback(null, output);
};

从 Lambda 控制台看到的错误消息

{
  "errorType": "Runtime.UserCodeSyntaxError",
  "errorMessage": "SyntaxError: await is only valid in async function",
  "trace": [
    "Runtime.UserCodeSyntaxError: SyntaxError: await is only valid in async function",
    "    at _loadUserApp (/var/runtime/UserFunction.js:98:13)",
    "    at Object.module.exports.load (/var/runtime/UserFunction.js:140:17)",
    "    at Object.<anonymous> (/var/runtime/index.js:45:30)",
    "    at Module._compile (internal/modules/cjs/loader.js:778:30)",
    "    at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)",
    "    at Module.load (internal/modules/cjs/loader.js:653:32)",
    "    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)",
    "    at Function.Module._load (internal/modules/cjs/loader.js:585:3)",
    "    at Function.Module.runMain (internal/modules/cjs/loader.js:831:12)",
    "    at startup (internal/bootstrap/node.js:283:19)"
  ]
}

我已经在没有 lambda 相关内容的情况下测试了它的基本代码,并且 JS 文件中的 async/await 作为脚本运行并且运行良好。

我知道问题在于将其转换为 lambda,并且与 Lambda 的异步/等待有关。

我怎样才能让我的 Lambda 执行 DB 调用并运行 forEach 将结果数组中的每个项目放入 SQS 消息中?

【问题讨论】:

    标签: node.js mongodb mongoose aws-lambda amazon-sqs


    【解决方案1】:

    你得到的错误是因为你试图在你的forEach 中使用await,而不是async。但是,不要认为您也可以将其设为 async 函数。

    最好的解决方案是停止使用.forEach,而使用更现代的for/of。你的 for 循环看起来像这样:

            for (let companyID of results) {
                let params = {
                    MessageBody: companyID,
                    QueueUrl: process.env.incidentsQueue,
                    DelaySeconds: 0
                };
    
                try {
                    const data = await sqs.sendMessage(params).promise();
    
                    logger.info(data)
                }
                catch (err) {
                    logger.error(err);
                }
            }
    

    注意,我还更改了调用 sendMessage 以使用正确的等待。

    【讨论】:

    • 谢谢你的工作!所以要了解更多,为什么 forEach 通常不适合与 Lambda 一起使用?同样在 try catch 中,如果我实际上没有在代码中使用 data 作为承诺,是否还需要使用 .promise()
    • .forEach 函数不适用于异步,因此如果您需要 await 任何内容(不仅仅是在 Lambda 中),它也将不起作用。对于 Lambda,您需要使用 async 或使用回调。 See the documentation 关于它的工作原理。至于.promise(),您需要使用await,如果您在async 函数中,则需要它。
    • 谢谢你现在更有意义了:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-12
    • 2020-11-10
    • 2021-01-09
    • 1970-01-01
    • 2016-10-16
    相关资源
    最近更新 更多