最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

amazon web services - How to retrieve multiple objects from AWS S3 using Javascript and then perform a function when they have b

programmeradmin6浏览0评论

The code below will retrieve at least one object (possibly two) from 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.

After the objects have been retrieved I want to do some image position (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.

How do I ensure I receive the objects from S3 before I attempt to carry out my other function to manipulate the images?

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.

The code below will retrieve at least one object (possibly two) from 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.

After the objects have been retrieved I want to do some image position (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.

How do I ensure I receive the objects from S3 before I attempt to carry out my other function to manipulate the images?

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.

Share Improve this question edited Jul 11, 2017 at 9:06 Joe Ainsworth asked Jul 11, 2017 at 8:56 Joe AinsworthJoe Ainsworth 5712 gold badges7 silver badges20 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 4

Key is to use Promise Objects

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. 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

Download multiple files using aws s3

发布评论

评论列表(0)

  1. 暂无评论