How to download a file from Amazon S3 bucket in node.js synchronously

Sumit picture Sumit · Jul 2, 2017 · Viewed 8.6k times · Source

I have to download multiple files from S3 bucket using node.js. For that I have to write a for loop & call the s3.getObject(param) method to download. After the files are downloaded I have to merge their contents.

I have written like this:

var fileContentList = new ArrayList();

for(i=0; i<fileNameList.length i++){
    s3.getObject({ Bucket: "my-bucket", Key: fileNameList.get(i) }, function (error, data) {
    if (error != null) {
      alert("Failed to retrieve an object: " + error);
    } else {
      alert("Loaded " + data.ContentLength + " bytes");
      fileContentList.add(data.Body.toString());
    }
  }
);
}

//Do merging with the fileContentList.

But as s3.getObject is an asynchronous call the current thread moves on & nothing gets added to the fileContentList while I am doing the merging.

How can I solve the problem? Any idea?
Is their any synchronous method in aws-sdk to download file?

Answer

S&#233;bastian Guesdon picture Sébastian Guesdon · Jul 2, 2017

Promises is better way,

var getObject = function(keyFile) {
    return new Promise(function(success, reject) {
        s3.getObject(
            { Bucket: "my-bucket", Key: keyFile },
            function (error, data) {
                if(error) {
                    reject(error);
                } else {
                    success(data);
                }
            }
        );
    });
}

var promises = [];
var fileContentList = new ArrayList();

for(i=0; i<fileNameList.length i++){
    promises.push(getObject(fileNameList.get(i)));
}

Promise.all(promises)
.then(function(results) {
    for(var index in results) {
        var data = results[index];
        fileContentList.add(data.Body.toString());
    }
    // continue your process here
})
.catch(function(err) {
    alert(err);
});