尝试检查嵌套异步中是否存在 s3 存储桶项目
Attempting to check if s3 bucket item exists within nested asyncs
我有一个无服务器 Lambda 函数,它响应 S3 s3:ObjectCreated
事件,尝试使用 AWS JavaScript 使用以下代码检查 S3 存储桶中是否存在单独的项目] SDK:
exports.somethingSomeSomething = async (event) => {
event.Records.forEach(async (record) => {
let tst = await s3.headObject({
Bucket: "mybucket",
Key: "something.gz"
}).promise()
console.log(tst)
})
};
我对 JS 中的 promises 很生疏,所以我不确定为什么这段代码不起作用。作为参考,它没有输出任何东西就死了。
但是,以下确实有效:
exports.somethingSomething = async (event) => {
let tst = await s3.headObject({
Bucket: "mybucket",
Key: "something.gz"
}).promise()
console.log(tst)
console.log("RED")
};
我怎样才能让代码的初始位工作,我做错了什么?
这是因为你的代码是 async
,但是传递给你的 forEach
循环的函数也是 async
,所以你有一个 async
函数调用另一个块async
代码,因此您失去了对流程的控制。 forEach
中的任何内容都将 运行(尽管 forEach
之后的任何内容将在 forEach
中的任何内容之前 运行),但它会异步执行并且您无法跟踪它的执行。
但如果代码如我所说,会 运行,为什么看不到结果?
嗯,那是因为 Lambda 会在该代码有机会执行之前终止。如果您在本地 运行 同一段代码,您会发现它 运行 很好,但是由于原始代码 运行 在 Lambda 之上,您无法控制当它终止时。
这里有两个选择:
最简单的方法是获取 Records 数组中的第一项,因为 s3 事件每次调用仅发送一个事件。它是数组的原因是因为 AWS 的工作方式(所有事件的通用接口)。无论如何,您的 forEach
没有使用 Record
对象的任何内容,但是如果您想使用它的任何属性,只需引用第 0 个位置,如下所示:
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 循环遍历记录(尽管同样对于 s3 事件没有必要),请改用 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
,因此 await
在其中完全有效。
更多关于 async/await and for..of
我有一个无服务器 Lambda 函数,它响应 S3 s3:ObjectCreated
事件,尝试使用 AWS JavaScript 使用以下代码检查 S3 存储桶中是否存在单独的项目] SDK:
exports.somethingSomeSomething = async (event) => {
event.Records.forEach(async (record) => {
let tst = await s3.headObject({
Bucket: "mybucket",
Key: "something.gz"
}).promise()
console.log(tst)
})
};
我对 JS 中的 promises 很生疏,所以我不确定为什么这段代码不起作用。作为参考,它没有输出任何东西就死了。
但是,以下确实有效:
exports.somethingSomething = async (event) => {
let tst = await s3.headObject({
Bucket: "mybucket",
Key: "something.gz"
}).promise()
console.log(tst)
console.log("RED")
};
我怎样才能让代码的初始位工作,我做错了什么?
这是因为你的代码是 async
,但是传递给你的 forEach
循环的函数也是 async
,所以你有一个 async
函数调用另一个块async
代码,因此您失去了对流程的控制。 forEach
中的任何内容都将 运行(尽管 forEach
之后的任何内容将在 forEach
中的任何内容之前 运行),但它会异步执行并且您无法跟踪它的执行。
但如果代码如我所说,会 运行,为什么看不到结果?
嗯,那是因为 Lambda 会在该代码有机会执行之前终止。如果您在本地 运行 同一段代码,您会发现它 运行 很好,但是由于原始代码 运行 在 Lambda 之上,您无法控制当它终止时。
这里有两个选择:
最简单的方法是获取 Records 数组中的第一项,因为 s3 事件每次调用仅发送一个事件。它是数组的原因是因为 AWS 的工作方式(所有事件的通用接口)。无论如何,您的 forEach
没有使用 Record
对象的任何内容,但是如果您想使用它的任何属性,只需引用第 0 个位置,如下所示:
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 循环遍历记录(尽管同样对于 s3 事件没有必要),请改用 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
,因此 await
在其中完全有效。
更多关于 async/await and for..of