尝试检查嵌套异步中是否存在s3存储桶项

时间:2019-05-13 06:57:09

标签: amazon-s3 async-await es6-promise serverless-framework

我有一个无服务器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")

};

如何使代码的最初部分起作用,我在做错什么?

1 个答案:

答案 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/awaitfor..of的更多信息