AWS Lambda函数不会首次发送Message,但会随后发送所有后续消息

时间:2020-01-28 12:27:55

标签: javascript node.js amazon-web-services aws-lambda amazon-sqs

我有一个通过API网关触发的lambda函数(有效)。

然后,lambda将一些数据添加到DynamoDB中(这有效)

然后调用我创建的将数据发送到SQS的函数

export const AddToQueue = async vehicleId => {
  const QueueParams = {
    DelaySeconds: process.env.QUEUE_DELAY,
    MessageAttributes: {},
  };

  QueueParams.MessageAttributes.vehicleId = {
    DataType: 'String',
    StringValue: vehicleId,
  };

  QueueParams.QueueUrl = 'my-queue-url';
  QueueParams.MessageBody = `vehicle: ${vehicleId} - ${new Date().toISOString()}`;

  try {
    await sqs.sendMessage(QueueParams).promise();
    console.log(`SQS:SUCCESS - AddToQueue - ${vehicleId}`);
  } catch (error) {
    console.log(`SQS:ERROR - AddToQueue - ${error}`);
  }
};

第一次发生此消息不会到达SQS,但是会将其他任何后续消息添加到队列并进行处理。我已经尝试了很多IAM权限,队列上的设置,重新创建队列的方法,但是这些都没有帮助。

我没有收到成功或错误消息,因此无法调试任何问题。

3 个答案:

答案 0 :(得分:3)

我不是专家,但是我以前曾经历过这种行为,在这种情况下,第一次调用中的某些异步代码要么似乎未执行,要么其执行似乎被延迟(例如,后续调用执行的动作出现了)以上一次通话的数据为基础。

在所有情况下,这都是由于未正确等待异步代码所致。我对javascript和Lambda的了解不足,无法解释其行为,尤其是延迟-在处理程序返回后但容器仍在运行时,诺言能否解决?但是我知道的是,如果lambda在promise(异步函数返回promise)被解决之前返回(因此在异步代码完成运行之前,这导致观察到的代码行为被延迟或未执行),那么它们尚未正确等待。

答案 1 :(得分:0)

可能您不在等待正在调用AddToQueue()的异步函数中

如果您没有在异步函数中调用AddtoQueue()并在其中等待,则执行该代码后,将运行AddToQueue。

所以让我举个例子。

您在测试目录中有2个文件。

await.js main.js

await.js是:

module.exports = async ()=> {

await new Promise((res, rej)=>{
    setTimeout(()=>{
        res(console.log('Running'));
    }, 2000)
})

}

还有main.js

console.log('Hello')
require('./await')();

console.log('World')

运行main.js时,node main.jsHello world将运行,然后在诺思解决后,它将从队列中推送到运行堆栈并运行最后一个堆栈。

Hello
World
// After 2 secs
Running

但是如果在main.js中

(async ()=>{
console.log('Hello')
await require('./await')();

console.log('World')
})()

您让javascript引擎知道,这是一个异步函数,在运行其他模块之前等待该模块,您将获得预期的结果。

Hello
// After 2 seconds
Running
World

基本上,您是在告诉JavaScript引擎I do not want you to run it your way, but run it my way

答案 2 :(得分:0)

我刚刚遇到了一个与此非常相似的问题,我的问题与没有像接受的答案中提到的@404 那样正确等待有关。

具体来说,我使用 forEach 迭代数组并在回调中调用 await

// causing weird behavior

async function invokeLambdas(teams) {
  teams.forEach(async (team) => {
    await utils.invokeLambda(team) // fn has a Lambda invoke in it
  });

我通过删除 forEach 并将其替换为常规 for 循环并按照建议在内部等待来解决此问题 here

async function invokeLambdas(teams) {
    for (const team of teams) {
        await utils.invokeLambda(team)
    }
 }
相关问题