belostoky
belostoky

Reputation: 974

How to upload files to s3 synchronously using node.js api

I have the following piece of code:

array.forEach(function (item) {

       // *** some processing on each item ***

        var params = {Key: item.id, Body: item.body};
        s3bucket.upload(params, function(err, data) {
            if (err) {
              console.log("Error uploading data. ", err);
            } else {
              console.log("Success uploading data");
        }});
  });

Because s3bucket.upload is being executed asynchronously - the loop finishes before uploading all the items.

How can I force s3bucket.upload to be synchronous?

Meaning don't jump to next iteration until this item was uploaded (or failed) to S3.

Thanks

Upvotes: 5

Views: 7406

Answers (3)

Marck Duilberg
Marck Duilberg

Reputation: 37

You could pass a post back function, this way the rest of the code is executed only when the upload has been completed. This does not answer your question but could be an alternative option:

array.forEach(function (item) {

   // *** some processing on each item ***

    var params = {Key: item.id, Body: item.body};
    var f1=function(){
       // stuff to do when upload is ok!
     }
      var f2=function(){
       // stuff to do when upload fails
     }
    s3bucket.upload(params, function(err, data) {

        if (err) {
         f2();
          console.log("Error uploading data. ", err);
         // run my function

        } else {
       // run my function
          f1();
          console.log("Success uploading data");
    }});

  });

Upvotes: 2

Erez
Erez

Reputation: 1750

Better to use promises as suggested in one of the comments:

const uploadToS3 = async (items) => {
  for (const item of array) {
    const params = { Key: item.id, Body: item.body };
    try {
      const data = await s3bucket.upload(params).promise();
      console.log("Success uploading data");
    } catch (err) {
      console.log("Error uploading data. ", err);
    }
  }
}

Upvotes: 3

Krishna Srinivas
Krishna Srinivas

Reputation: 1700

you can use https://github.com/caolan/async#each each or eachSeries

function upload(array, next) {
    async.eachSeries(array, function(item, cb) {
        var params = {Key: item.id, Body: item.body};
        s3bucket.upload(params, function(err, data) {
            if (err) {
              console.log("Error uploading data. ", err);
              cb(err)
            } else {
              console.log("Success uploading data");
              cb()
            }
        })
    }, function(err) {
        if (err) console.log('one of the uploads failed')
        else console.log('all files uploaded')
        next(err)
    })
}

Upvotes: 4

Related Questions