node.js - Promise 或与 Node js 异步

标签 node.js amazon-s3 aws-lambda

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

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

所以我需要在upload最后一次返回时调用context.done()

研究一下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();

最佳答案

看看他们如何使用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. 中所示的方式使用它

关于node.js - Promise 或与 Node js 异步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29416635/

相关文章:

amazon-web-services - 无服务器函数中的并发问题 (AWS/Azure)

node.js - 如何从nodejs中的process.environment中提取环境变量

python - 使用 Python 从公共(public) AWS S3 下载文件/文件夹,无需凭证

IOS AWS s3 bucket 图片上传问题

reactjs - 如何为 React 应用程序保存图像

node.js - AWS Lambda GraphicsMagick 错误 : gm/convert binaries can't be found"

amazon-web-services - 为什么我的 Lambda 无法访问互联网?

python - 如何将多个图像作为输入传递给 python 脚本

node.js - Node JS 中 MongoDB 对象 ID 的 BSON/二进制到字符串

node.js - 迪尔德 : lazy symbol binding failed