我有一个通过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权限,队列上的设置,重新创建队列的方法,但是这些都没有帮助。
我没有收到成功或错误消息,因此无法调试任何问题。
答案 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.js
,Hello 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)
}
}