我有一个无服务器Lambda函数,该函数响应S3 s3:ObjectCreated
事件,使用AWS JavaScript SDK使用以下代码尝试检查S3存储桶中是否存在单独的项目:
exports.somethingSomeSomething = async (event) => {
event.Records.forEach(async (record) => {
let tst = await s3.headObject({
Bucket: "mybucket",
Key: "something.gz"
}).promise()
console.log(tst)
})
};
我对JS中的promise感到非常生疏,所以我不确定为什么这段代码不起作用。作为参考,它只是死掉而没有输出任何东西。
但是,以下起作用:
exports.somethingSomething = async (event) => {
let tst = await s3.headObject({
Bucket: "mybucket",
Key: "something.gz"
}).promise()
console.log(tst)
console.log("RED")
};
如何使代码的最初部分起作用,我在做错什么?
答案 0 :(得分:1)
这是因为您的代码是async
,但是传递给您的forEach
循环的函数也是async
,所以您有一个async
函数调用了另一块{{ 1}}代码,因此您将失去对流程的控制。 async
内部的任何内容都将运行(尽管forEach
之后的任何内容都将在forEach
内部的任何内容之前运行),但是它将异步执行,您无法跟踪其执行情况。
但是,如果我要说的代码能够运行,为什么看不到结果呢?
好吧,这是因为Lambda将在该代码有机会执行之前终止。如果您在本地运行同一段代码,您会看到它会很好地运行,但是由于原始代码在Lambda之上运行,因此您无法控制终止时间。
您在这里有两个选择:
最简单的方法是获取Records数组中的第一项,因为s3事件每次调用发送一个事件,并且仅发送一个事件。之所以是数组,是因为AWS的工作方式(所有事件的通用接口)。无论如何,您的forEach
并没有使用forEach
对象的任何东西,但是如果您想使用它的任何属性,只需引用第0个位置即可,例如:
Record
如果您仍想使用for循环遍历记录(尽管同样,对于s3事件而言则不必要),请改用exports.somethingSomeSomething = async (event) => {
const record = event.Records[0]
//do something with record
const tst = await s3.headObject({
Bucket: "mybucket",
Key: "something.gz"
}).promise()
console.log(tst)
};
循环:
for of
由于exports.somethingSomeSomething = async (event) => {
for (const record of event.Records) {
// do something with record
const tst = await s3.headObject({
Bucket: "mybucket",
Key: "something.gz"
}).promise()
console.log(tst)
}
};
只是一个常规循环,它将使用正在执行的函数中的for of
,因此async
在其中完全有效。
有关async/await和for..of的更多信息