2015-04-02 91 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.

顯示