在AWS Lambda中使用Async/Await写入S3存储桶

17

我一直在使用以下代码(现在已添加了“await”)将文件发送到S3,虽然这段代码可以在我的lambda代码中正常工作,但是当我开始传输像MP4这样的大文件时,我感觉需要使用async/await。

如何完全将此代码转换为async/await?

exports.handler = async (event, context, callback) => {
...
// Copy data to a variable to enable write to S3 Bucket
var result = response.audioContent;
console.log('Result contents ', result);

// Set S3 bucket details and put MP3 file into S3 bucket from tmp
var s3 = new AWS.S3();
await var params = {
Bucket: 'bucketname',
Key: filename + ".txt",
ACL: 'public-read',
Body: result
};

await s3.putObject(params, function (err, result) {
if (err) console.log('TXT file not sent to S3 - FAILED'); // an error occurred
else console.log('TXT file sent to S3 - SUCCESS');    // successful response
context.succeed('TXT file has been sent to S3');
});

2
你不需要使用 await var params = ...await 只对 promises 有用。 - djheru
2个回答

36

您只能等待返回Promise的函数。 s3.putObject 不返回Promise(与大多数带回调函数的函数类似)。 它返回一个Request对象。 如果您想使用async/await,您需要在s3.putObject调用的末尾链接.promise()方法并删除回调(https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Request.html#promise-property)

try { // You should always catch your errors when using async/await
  const s3Response = await s3.putObject(params).promise();
  callback(null, s3Response);
} catch (e) {
  console.log(e);
  callback(e);
}

我认为这是正确的轨道,除了您可能也不想在此处使用已弃用的 context.succeed(),因为那会混合异步/等待和回调。既然您在异步函数(处理程序)中,那么请返回响应或承诺,对吗? - Michael - sqlbot
在async/await情况下,context.succeed(s3Response);应该替换为什么? - Gracie
也许是 callback(null, s3Response); - Gracie
1
是的,我之前不确定context.succeed该怎么用。后来做了一些研究,发现context对象主要是为了提供关于lambda请求的额外信息(https://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-context.html)。你需要调用callback(null, s3Response)而不是context.succeed。我会更新我的回答。 - djheru

9
如@djheru所说,Async/Await只能与返回Promise的函数一起使用。 我建议创建一个简单的包装函数来解决这个问题。
const putObjectWrapper = (params) => {
  return new Promise((resolve, reject) => {
    s3.putObject(params, function (err, result) {
      if(err) reject(err);
      if(result) resolve(result);
    });
  })
}

那么你可以像这样使用它:

const result = await putObjectWrapper(params);

这是一个关于Promises和Async/Await的非常好的资源:

https://javascript.info/async


3
如果(err) resolve(err); 应该替换为 if(err) reject(err);。 - Hemant Kumar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接