我一直在尝试(并且失败)使用Node version 8.10中的s3.getObject从S3存储桶加载文件。
我找到了一篇很棒的帖子,上面的答复几乎有效here,但是该语法在8.10中不太起作用,而且无论我如何重新排列代码,我都无法使其正常工作。
var AWS = require('aws-sdk')
var s3 = new AWS.S3();
var fileData = null;
exports.handler = (event, context, callback) => {
console.log('I am in the main procedure');
var params = {
Bucket: "change_for_your_bucket",
Key: "change_to_your_json_file"
};
fetchDataFromS3(params);
console.log('I am in the main procedure, the function above should be waiting but it is not');
waitForFileLoadBeforeDoingSomething(event, context, callback);
const s = JSON.stringify(fileData.Body.toString('utf-8'));
console.log(`this is the file: ${s}`);
console.log('I have the file!(dg.2)');
};
function fetchDataFromS3(params)
{
console.log('-------------- fetchDataFromS3:Start -------------------------');
// gets the object from s3 => promise
const uploadPromise = s3.getObject(params).promise();
// returns the body of the s3 object
uploadPromise
.then(function(data) {
console.log("successfully downloaded data");
fileData = data.Body.toString();
})
.catch(function download(err) {console.log(err,err.stack); throw err;});
console.log('-------------- fetchDataFromS3:Done -------------------------');
}
function waitForFileLoadBeforeDoingSomething(event, context, callback){
if(!fileData){
console.log('No file available to me as yet, lets sleep for a bit');
setTimeout(function(){
waitForFileLoadBeforeDoingSomething(event, context, callback);
}, 300);
}
}
输出如下。
Function Logs:
START RequestId: cb16f155-c0d7-11e8-ad01-f5991c5adaaf Version: $LATEST
2018-09-25T15:29:29.759Z cb16f155-c0d7-11e8-ad01-f5991c5adaaf I am in the main procedure
2018-09-25T15:29:29.759Z cb16f155-c0d7-11e8-ad01-f5991c5adaaf -------------- fetchDataFromS3:Start -------------------------
2018-09-25T15:29:29.811Z cb16f155-c0d7-11e8-ad01-f5991c5adaaf -------------- fetchDataFromS3:Done -------------------------
2018-09-25T15:29:29.811Z cb16f155-c0d7-11e8-ad01-f5991c5adaaf I am in the main procedure, the function above should be waiting but it is not
2018-09-25T15:29:29.811Z cb16f155-c0d7-11e8-ad01-f5991c5adaaf No file available to me as yet, lets sleep for a bit
2018-09-25T15:29:29.812Z cb16f155-c0d7-11e8-ad01-f5991c5adaaf TypeError: Cannot read property 'Body' of null
at exports.handler (/var/task/dg3.js:17:39)
您可以看到我没有点击“成功下载数据”行,并且如果我犯了一个错误并且该函数仍在异步运行,或者如果我已经有了promise的语法,我将无法解决。错误的。
答案 0 :(得分:1)
首先,您必须更改入口点方法。就像您在尝试使用8.10节点运行时之前提到的那样,然后是以下代码部分:
exports.handler = (event, context, callback) => {}
您必须更改为:
export async function <function_name>(event) {}
ref:https://aws.amazon.com/blogs/compute/node-js-8-10-runtime-now-available-in-aws-lambda/
然后该函数的路径应为:
<module_name>.<function_name>
此外,您不需要以下代码部分:
function waitForFileLoadBeforeDoingSomething(event, context, callback){
if(!fileData){
console.log('No file available to me as yet, lets sleep for a bit');
setTimeout(function(){
waitForFileLoadBeforeDoingSomething(event, context, callback);
}, 300);
}
}
然后摆脱var声明。不要搞乱范围。只需使用:
const AWS = require('aws-sdk');
下一步是创建一个S3实例:
const S3 = new AWS.S3({region: process.env.AWS_REGION, apiVersion: '2006-03-01'});
// with region of your AWS account and current API verstion;
为您的提取方法声明参数:
const params =
{
Bucket: 'STRING_VALUE', // a path to your Bucket
Key: 'STRING_VALUE' // a key (literally a path to your file)
}
ref:https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#getObject-property
您不必对事件进行字符串化,因为它已经被字符串化了:
const s = JSON.stringify(fileData.Body.toString('utf-8'));
最后:
try
{
const result = await S3.getObject(params).promise();
// if successful then:
console.log(`Check the result: ${result}`);
}
catch (ex) // if an error occured
{
console.error(ex);
}
还请确保运行时5分钟(您可以调整后仅用于调试)并增加lambda的内存(也用于测试)。