2015-04-02 124 views
1

我有这么多的代码,它从S3存储桶获取图像,将其保存到Lambda上的临时文件,将其调整为4种不同的大小,并根据大小将其保存到不同的文件夹中,他们将图像放回s3存储桶中也放入不同的文件夹中。Promise or Async with Node js

但是,在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(); 

回答

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.

显示