【问题标题】:AWS Lambda using s3 getObject function nothing happeningAWS Lambda 使用 s3 getObject 函数什么也没发生
【发布时间】:2019-05-08 16:44:51
【问题描述】:

这是使用内联编辑器的 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;
};

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

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

【问题讨论】:

    标签: node.js amazon-s3 aws-lambda aws-sdk aws-sdk-js


    【解决方案1】:

    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;
    };
    

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

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

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

    【讨论】:

    • 如何像这样处理lambda中的多个getobject请求?
    • 好的,所以我尝试使用forEach 循环遍历按键并调用getobject,但它没有工作,因为它涉及回调函数。虽然简单的 for 循环可以进行多次 getobject 调用,然后将它们的结果收集到一个数组中
    • 是的,forEach 不起作用(至少不是天真的方法)。我要做的是使用Array.map() 生成一个承诺列表,并在结果列表中使用Promise.all()
    • 好的。这个Promise.all 我试过了,但可能遗漏了一些它也不起作用的东西。有时间会再检查一次。谢谢。
    猜你喜欢
    • 2016-09-29
    • 2020-04-23
    • 2019-08-24
    • 1970-01-01
    • 2019-12-04
    • 2016-10-08
    • 1970-01-01
    • 1970-01-01
    • 2018-07-03
    相关资源
    最近更新 更多