与节点js的Promise或Async

时间:2015-04-02 15:22:16

标签: node.js amazon-s3 aws-lambda

我有大量的代码从S3存储桶中获取图像,将其保存到Lambda上的临时文件中,将其大小调整为4种不同的大小,根据大小将其保存到不同的文件夹中,然后将图像重新放入s3桶也进入不同的文件夹。

然而,当在Lambda上运行时,我必须在整个过程结束时调用context.done(),否则上下文将保持活动状态,直到Lambda超时。

所以当context.done()最后一次返回时,我需要致电upload

调查asyncpromises两个选项,这些选项可能需要更少的重构才能使用我的代码?

// dependencies
var AWS = require('aws-sdk');
var gm = require('gm').subClass({ imageMagick: true });
var fs = require("fs");

// get reference to S3 client
var s3 = new AWS.S3();

var _800px = {
    width: 800,
    destinationPath: "large"
};

var _500px = {
    width: 500,
    destinationPath: "medium"
};

var _200px = {
    width: 200,
    destinationPath: "small"
};

var _45px = {
    width: 45,
    destinationPath: "thumbnail"
};

var _sizesArray = [_800px, _500px, _200px, _45px];

var len = _sizesArray.length;
 module to be exported when in production
ports.AwsHandler = function(event, context) {
  // Read options from the event.
  var srcBucket = event.Records[0].s3.bucket.name;
  var srcKey = event.Records[0].s3.object.key;
  var dstnFolder = "/tmp";
  // function to determine paths
  function _filePath (directory, i) {
      if ( directory === false ) {
          return "dst/" + _sizesArray[i].destinationPath + "/" + srcKey;
      } else if ( directory === true ) {
          return dstnFolder + "/" + _sizesArray[i].destinationPath + "/" + srcKey;
      }
  };
  for ( var i = 0; i<len; i++) {
      fs.mkdir("/tmp" + "/" + _sizesArray[i].destinationPath, function (err) {
          if (err) {
              console.log(err);
          }
      });
  };
  // Infer the image type.
  var typeMatch = srcKey.match(/\.([^.]*)$/);
  if (!typeMatch) {
      console.error('unable to infer image type for key ' + srcKey);
      return;
  };
  var imageType = typeMatch[1];
  if (imageType != "jpg" && imageType != "png") {
      console.log('skipping non-image ' + srcKey);
      return;
  };
  function download () {
      s3.getObject({
              Bucket: srcBucket,
              Key: srcKey
          },
          function (err, response) {
              if (err) {
                  console.error(err);
              }
              fs.writeFile("/tmp" + "/" + srcKey, response.Body, function (err) {
                  transform();
              })
          }
      );
  };
  function transform () {
      var _Key,
          _Size;
      for ( var i = 0; i<len; i++ ) {
          // define path for image write
          _Key = _filePath (true, i);
          // define sizes to resize to
          _Size = _sizesArray[i].width;
          // resize images
          gm("/tmp/" + srcKey)
              .resize(_Size)
              .write(_Key, function (err) {
                  if (err) {
                      return handle(err);
                  }
                  if (!err) {
                      // get the result of write
                      var readPath = this.outname;
                      var iniPath = this.outname.slice(4);
                      var writePath = "dst".concat(iniPath);
                      read(err, readPath, writePath, upload);
                  }
              });
      };
  };
  function read (err, readPath, writePath, callback) {
      // read file from temp directory
      fs.readFile(readPath, function (err, data) {
          if (err) {
              console.log("NO READY FILE FOR YOU!!!");
              console.error(err);
          }
          callback(data, writePath);
      });
  };
  function upload (data, path) {
      // upload images to s3 bucket
      s3.putObject({
              Bucket: srcBucket,
              Key: path,
              Body: data,
              ContentType: data.type
          },
          function (err) {
              if (err) {
                  console.error(err);
              }
              console.log("Uploaded with success!");
          });
  }
  download();

1 个答案:

答案 0 :(得分:1)

Q中查看他们如何使用example

您的代码最终会与

非常相似
download()
.then(transform)
.then(read)
.then(upload)
.catch(function (error) {
  // Handle any error from all above steps
  console.error(error);
})
.done(function() {
  console.log('Finished processing image');
  context.done();
});

您还可以查看async并使用它,因为它们显示在其他example.