使用 s3 getObject 函数的 AWS Lambda 什么也没发生

Ber*_*amb 4 amazon-s3 node.js aws-sdk aws-lambda aws-sdk-js

这是使用内联编辑器的 node.js 代码:

const AWS = require('aws-sdk');
const s3 = new AWS.S3();

console.log('Loading function');

exports.handler = async (event) => {
    // TODO implement
    var responseMsg = '';
    var bucket = '';
    var key = '';
    if ('Records' in event) {
        var s3Data = event.Records[0].s3;
        console.log('s3Data: ' + JSON.stringify(s3Data));
        bucket = s3Data.bucket.name;
        key = s3Data.object.key;
    }
    console.log('Bucket:' + bucket);
    console.log('Key:' + key);
    var params = { 
        Bucket: bucket,
        Key: key
    };
    console.log('Params:' + JSON.stringify(params));
    s3.getObject(params, function (err, data) {
       console.log('getObject');
       if (err) {
           console.log(err, err.stack);
           return err;
       } 
       responseMsg = data;
    });
    const response = {
        statusCode: 200,
        body: JSON.stringify(responseMsg),
    };
    return response;
};
Run Code Online (Sandbox Code Playgroud)

我知道我正在测试的密钥和存储桶存在于我的 S3 控制台中。我知道我可以在 LINQPad 中使用 C# 访问它们。

当我运行它时,我没有收到任何错误。我在响应正文中得到一个空字符串,而不是对象的内容。我也没有从 s3.getObject 中收到任何日志消息。

小智 15

调用s3.getObject是异步调用。当s3代码运行时,代码的执行继续进行。您需要明确地await为调用的承诺解决。

这就是你的方法(注意s3.getObject调用的变化):

const AWS = require('aws-sdk');
const s3 = new AWS.S3();

exports.handler = async (event) => {
    var params = { 
        Bucket: <bucket>,
        Key: <key>,
    };

    const data = await s3.getObject(params).promise();

    const response = {
        statusCode: 200,
        body: JSON.stringify(data),
    };
    return response;
};
Run Code Online (Sandbox Code Playgroud)

您可以使用try/catch块进行错误处理。

这里要理解的重要一点是执行的时间。调用 lambda 时,函数中的主线代码会按顺序调用。s3.getObject当来自 S3 的响应到达时,您传递给调用的回调函数会在您的 lambda 完成执行很久之后被调用。

您的return调用在回调运行之前执行,因此您会看到JSON.strigify(responseMsg)where的结果responseMsg保存了您给它的初始值,即空字符串''