尝试检查嵌套异步中是否存在 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