Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to synchronously upload files to S3 using aws-sdk?

I'm attempting to upload files to my S3 bucket and then return out of my upload function. The problem is that I'm returning out of the function before the upload returns the stored data.

I've attempted to use async/await with s3.upload, but I don't believe s3.upload is a promise so it doesn't do anything.

ex:

   for (const file of files) {
    const params = {
      Bucket: BUCKET_NAME,
      Key: file.name,
      Body: file.data
    };
    const stored = await s3.upload(params, (err, data) => {
      if (err) console.log("error", err, err.stack);
      return console.log(data);
    });
    console.log(stored);
   }
   console.log("leave loop")

I've attempted using the Async utility module with async.each and async.eachSeries as referenced in this stack answer like so:

  const saveFile = async file => {
    const params = {
      Bucket: BUCKET_NAME,
      Key: file.name,
      Body: file.data
    };
    s3.upload(params, (err, data) => {
      if (err) console.log("error", err, err.stack);
      console.log(data);
    });
  };

  await async.eachSeries(files, saveFile, err => {
    if (err) console.log(err);
  });

  console.log("leave loop")

But it is still hitting "leave" too soon. I'm misunderstanding something but I'm not sure what.

Update:

s3.upload returns a managedUpload object - that seems to be why await is triggering early. The callback is triggered when managedUpload is resolved/completed.

So is there a way to await the completed object instead of managedUpload?

like image 370
colemars Avatar asked Aug 08 '19 21:08

colemars


1 Answers

You should try to call promise() on the ManagedUpload in order to get a Promise and await its resolution:

for (const file of files) {
  const params = {
    Bucket: BUCKET_NAME,
    Key: file.name,
    Body: file.data
  };
  try {
    const stored = await s3.upload(params).promise()
    console.log(stored);
  } catch (err) {
    console.log(err)
  }
}
console.log("leave loop")
like image 191
antonku Avatar answered Oct 16 '22 00:10

antonku