javascript - 如何用数组链接 Promise

标签 javascript amazon-s3 promise aws-lambda

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

我的问题:我不知道如何将图片对象数组集成到 promise 流程中。我能找到的所有堆栈示例都显示了当所有数据已知时 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);
    })
  })
}

最佳答案

啊,你快明白了!您需要为此处生成的 promise 数组创建一个观察程序:pictureSizes.map(picture => resizePicture(result, picture))

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

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

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

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

关于javascript - 如何用数组链接 Promise,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39355517/

相关文章:

javascript - 在世博会中打开相机

java - 公开托管 Apache Tomcat 问题时的文件上传

amazon-web-services - AWS AccessDeniedException elastictranscoder :CreateJob

ssl - Amazon S3 数据完整性 MD5 与 SSL/TLS

javascript - 警告 - 未处理的 promise 拒绝 : Can't set headers after they are sent

javascript - 等待所有响应,然后调用函数

javascript - 带有 Bootstrap 下拉菜单的上下文菜单在 Firefox 中不起作用

javascript - React - 单独脚本中的组件不起作用

javascript - 如何重构这个 Redux 连接代码?

javascript - 在 AngularJS 中异步调用 hprose.httpclient