Reputation: 1932
I am trying to get a list of objects out of an S3 bucket and when I have a list of objects I would like to generate pre-signed URLs for these objects. The only way I could figure out how to do this was to use nested callback functions like so:
exports.handler = async (event, context, callback) => {
console.log('processing event: %j', event);
const bucket = process.env['s3_bucket'];
if (!bucket) {
callback(new Error("s3 bucket not set"));
}
const deviceId = event['deviceId'];
const params = getListObjectsParams(deviceId, bucket);
let count = 0;
await s3.listObjectsV2(params, function (err, data) {
if (err) callback("Error getting image list: " + err);
else {
data.Contents.forEach(function (image) {
count = count + 1;
const objectParams = getObjectParams(bucket, image.Key);
s3.getSignedUrl('getObject', objectParams, function (err, url) {
if (err) {
console.log("Error");
console.log(err);
//TODO: log error getting pre signed url
} else {
images.push(url);
}
});
});
}
});
callback(null, images);
};
I am having some trouble returning the images array as the function is completing before the calls to listObjectsV2 and each of the getSignedUrl complete. Here are my questions.
Upvotes: 0
Views: 191
Reputation: 78703
The AWS JavaScript SDK natively supports promises. Instead of this:
s3.listObjectsV2(params, function (err, data) {
// do something with data here in the callback
});
write this:
const data = await s3.listObjectsV2(params).promise();
// do something with data here
Note that await
may only be used in an async
function. If you aren't in an async function then you can fabricate one as follows (an immediately invoked async arrow function):
(async () => {
const data = await s3.listObjectsV2(params).promise();
// do something with data here
})();
Upvotes: 1
Reputation: 943591
How do I get the execution to wait for promises to complete before completing executing the function?
Inside an async
function, put await
in front of a promise.
You've done the first two of those, but s3.listObjectsV2
doesn't return a promise.
If you want to use await
with it then you must convert the existing callback API to a promise
Upvotes: 1