[英]How to retrieve multiple objects from AWS S3 using Javascript and then perform a function when they have been retrieved?
The code below will retrieve at least one object (possibly two) from AWS S3.下面的代码将从 AWS S3 中检索至少一个对象(可能是两个)。
I am using the AWS JS SDK and retrieve the objects from within a loop as there is noway to retrieve multiple objects with one request at this moment in time.我正在使用 AWS JS SDK 并从一个循环中检索对象,因为目前无法通过一个请求检索多个对象。
After the objects have been retrieved I want to do some image composition (the objects are images).检索到对象后,我想进行一些图像合成(对象是图像)。
My problem is that the rest of my code executes before I have successfully retrieved the objects.我的问题是我的其余代码在我成功检索对象之前执行。 I know this because objects
remains unchanged when logged to the console.我知道这是因为objects
在登录到控制台时保持不变。
How do I ensure I receive the objects from S3 before I attempt to carry out my other function to manipulate the images?在尝试执行其他功能来处理图像之前,如何确保从 S3 接收到对象?
var app = require('../application');
exports.generate = function (req, res) {
objects = {
logo: req.body.logo,
}
if (!req.body.background.startsWith('#')) {
objects.background = req.body.background;
}
for (type in objects) {
var params = {
Bucket: "my-bucket",
Key: objects[type]
};
app.s3.getObject(params, function(err, data) {
if (err) {
console.log(err, err.stack);
}
else {
objects[type] = data;
}
});
}
if (objects.background) {
gm(objects.logo).append(objects.background).write('temp.jpg', function() {
console.log('Logo and background have been appended');
});
}
console.log(objects);
console.log('Finished');
}
The console logs the following控制台记录以下内容
{ logo: 'Original 106fm Logo #268390.jpg', background: 'test.jpg' }
Finished
When the images are retrieved the log should be showing the data body for each image.检索图像时,日志应显示每个图像的数据主体。
Key is to use Promise Objects关键是使用Promise对象
app.get('/api/template', (req, res) => {
let promises = [getS3Object(`templates/x.tpl`),
getS3Object(`templates/y.tpl`),
getS3Object(`templates/z.tpl`),
getS3Object('templates/b.tpl')];
return Promise.all(promises)
.then((pres) => {
const iterable = [0, 1, 2, 3];
for (let value of iterable) {
if (!pres[value].statusCode) {
res.send(pres[value]);
}
}
})
.catch((res) => {
console.log(`Error Getting Templates: ${res}`);
});
});
const getS3Object = key => {
return new Promise((resolve, reject) => {
s3.getObject({
Key: key
}, (err, data) => {
if (err){
resolve(err)
} else {
resolve(data.Body)
}
})
})
}
This happens because your console.log
calls are executing prior to download files.发生这种情况是因为您的console.log
调用在下载文件之前执行。 What you can do is process files after receiving them.您可以做的是在收到文件后对其进行处理。
app.s3.getObject(params, function(err, data) {
if (err) {
console.log(err, err.stack);
}
else {
objects[type] = data;
//Here you have the downloaded files. Do your processing here
console.log(objects);
}
});
Asynchronous behavior is what you should read more about.异步行为是您应该阅读的更多内容。
[Update] you can use following wrapper module to download multiple files [更新] 你可以使用下面的包装器模块来下载多个文件
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.