【发布时间】:2018-12-13 06:08:20
【问题描述】:
所以我有以下代码。当我在本地运行它时,它按预期工作。当我将它发布到 lambda 时,它无法获取我的 S3 项目。我看到为我的请求创建了承诺,但 return Promise.all(ps) 永远不会返回预期值。我试图以几种不同的方式改变它,但总是没有。我将本地环境更新为与 lambda 相同(节点 8.10 和 aws-sdk 2.290.0),但它仍然可以在本地工作,但在托管时不能。
cloudwatch 日志显示它已结束且不包含错误,并在约 100 毫秒内结束。
我要求从 s3 获取 20 个对象,每个对象大小为 8k;我添加了一个中断来只检索 1 条记录,同样的情况发生了……什么也没有。
module.exports = async(messages) => {
try {
for (var rec of messages) {
debug('rec',rec);
let samples = await getRecordingPageSamples(rec.serialNumber,rec.recordingSet,rec.recording,rec.pages);
//NEVER GETS HERE IN LAMBDA
...
}
//NEVER GETS HERE IN LAMBDA
console.log('we are done here.');
} catch (e) {
console.log('unhandled',e);
}
};
function getRecordingPageSamples(serialNumber,recordingSet,recording,pages){
let ps = getObjectGenerator(pages.map(x=>[process.env.s3EeegPageBucket,genRecordingSamplePath(serialNumber,recordingSet,recording,x)]));
ps = ps.map( p=> p.then(obj=>{
console.log('done',obj[1]);
return obj.slice(0,2).concat([obj[1].split(s.FILE_NAME_SEP)[2],obj[2].Body.toString()]);
}));
// here ps is an array of promises ps [ Promise { <pending> } ]
return Promise.all(ps);
}
function getObjectGenerator(list){
let ps = [];
for (let x of list){
//DOES GET HERE IN LAMBDA
console.log('requesting obj',x);
ps.push( getObject(x[0],x[1]));
}
return ps;
}
const getObject = (bucket,key) => {
return s3.getObject({
Bucket: bucket, // Assuming this is an environment variable...
Key: key
})
.promise()
.then(data=>{
//NEVER GETS HERE IN LAMBDA
console.log('got it',key);
return [bucket,key,data];
});
问题解决了。此模块上方还有另一个包装函数,它是一个异步函数,但没有使用 await 关键字。菜鸟失误!
【问题讨论】:
-
您是否正确地等待来自您的 lambda 处理函数的顶级函数?
-
@Evert 你是我的 GD 英雄...在那里我尝试重用代码,我错过了包含函数异步时的等待。干杯!
-
很高兴我能帮上忙!我也遇到了一些事情 =) 有一种在本地机器上运行它的好方法可能会有所帮助。让处理函数何时结束更明显。
-
我在本地运行它,但似乎运行完成。我开始追踪它,因为我添加了更多日志记录,显示 finally 在承诺完成之前运行。我想以类似的方式在本地发生这种情况的唯一方法是创建另一个包装器,在处理程序返回后杀死节点进程。关于如何做到这一点的任何想法?
-
我知道有一些工具可以为您完成所有这些工作,但我这样做的方式是在处理程序返回后输出一点点。
process.exit()更具侵略性,但也可以工作。
标签: lambda promise async-await aws-sdk-js