如何将promises与数组链接起来

时间:2016-09-06 18:23:05

标签: javascript amazon-s3 promise aws-lambda

问题:使用Node 4.3和图形魔术创建AWS Lambda函数以调整上传的S3图片的大小。

我的问题:我无法弄清楚如何将一组图片对象集成到promise流程中。我能找到的所有堆栈示例都显示了在所有数据都已知的情况下所宣传的对象数组。但我需要首先读取图像数据,然后将其传递给调整大小函数。

以下函数在resizePicture结算之前完成。我知道问题不是返回Promise并以正确的顺序解决。我很难过。

var pictureSizes = [
  {width: 100, size: 'thumbnail', suffix: '_t'},
  {width: 300, size: 'small', suffix: '_s'},
  {width: 600, size: 'medium', suffix: '_m'},
  {width: 1000, size: 'large', suffix: '_l'}
];

exports.handler = function(event, context) {

  var srcBucket = event.Records[0].s3.bucket.name;.
  var srcKey = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, " "));
  var dstBucket = srcBucket + "pictures";
  var typeMatch = srcKey.match(/\.([^.]*)$/);
  var fileName = path.basename(srcKey);

  downloadImage({ Bucket: srcBucket, Key: srcKey})
  .then(result => pictureSizes.map(picture => resizePicture(result, picture)))
  .then(result => saveImage(result, dstBucket, fileName))
  .catch(err => console.log('error', err))
}

function downloadImage(params) {
  console.log('download Image', params);
  return new Promise(function(resolve, reject) {
    s3.getObject(params, function(err, data) {
      if (err) {
        reject(err);
      }
      resolve(data);
    })
  });
}

function resizePicture(result, picture) {
  return new Promise(function(resolve, reject) {
    const extension = result.ContentType.split('/')[1];
    gm(result.Body)
      .resize(picture.width)
      .toBuffer(extension, function(err, buffer) {
        if (err) {
          reject(err);
        } else {
          resolve({
            key: `${picture.suffix}.${extension}`,
            binary: buffer,
            ContentType: result.contentType
          })
        }
      });
  })
}

function saveImage(result, dstBucket, fileName) {
  return new Promise(function(resolve, reject) {
    s3.putObject({
      Bucket: dstBucket,
      Key: `${fileName}${result.key}`,
      Body: result.binary,
      ContentType: result.ContentType
    }, function(err, data) {
      if (err) {
        reject(err);
      }
      resolve(data);
    })
  })
}

1 个答案:

答案 0 :(得分:1)

啊,你差不多了!您需要为此处生成的承诺数组创建一个观察程序:/questions/39355114/select-image-from-gallery-and-show-in-an-imageview

尝试Bluebird's Promise.map,您的行可以阅读:

pictureSizes.map(picture => resizePicture(result, picture))

如果您不想拥有任何嵌套函数,#bind就是您想要的:

.then(result => Promise.map(pictureSizes, picture => resizePicture(result, picture)))