node.js Aws Lambda:将getObject转换为base64

时间:2019-01-14 12:47:56

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

我从这里https://dzone.com/articles/serverless-zipchamp-update-your-zip-files-in-s3-al修改了zip功能,因为它只能压缩文本,而不能压缩图像。

该问题出现在代码末尾的base64_encode函数中。我可以将base64字符串写入控制台,但不能将其返回给调用函数。

欢迎任何帮助。

let AWS = require('aws-sdk');
let JSZip = require("jszip");
let fs = require("fs");
const s3 = new AWS.S3();
let thebase='';


exports.handler = function (event, context, callback) {
    let myzip = event.zip;
    let modified = 0, removed = 0;
    let mypath = event.path;
    let mynewname = event.newname;
    let filename = event.filename;

	//get Zip file
    s3.getObject({
        'Bucket': "tripmasterdata",
        'Key': event.path+'/'+myzip,
       
    }).promise()
        .then(data => {
            let jszip = new JSZip();
            jszip.loadAsync(data.Body).then(zip => {
                // add or remove file
                if (filename !== '') {
                      //here I get the Image to be stored in the zip as base64 encoded string
                      thebase = base64_encode(mypath,filename,thebase);
                      console.log('AD:'+thebase); //<- this is always empty, WHY????
                      zip.file(mynewname, thebase, {createFolders: false,compression: "STORE",base64: true});
                      modified++;
                } else {
                      console.log(`Remove ${filename}`);
                      zip.remove(filename);
                      removed++;
                }

                let tmpzip = `/tmp/${myzip}`
                let tmpPath = `${event.path}`
                //Generating the zip
                console.log(`Writing to temp file ${tmpzip}`);
                zip.generateNodeStream({ streamFiles: true })
                    .pipe(fs.createWriteStream(tmpzip))
                    .on('error', err => callback(err))
                    .on('finish', function () {
                        console.log(`Uploading to ${event.path}`);
                        s3.putObject({
                            "Body": fs.createReadStream(tmpzip),
                            "Bucket": "xxx/"+tmpPath,
                            "Key": myzip,
                            "Metadata": {
                                "Content-Length": String(fs.statSync(tmpzip).size)
                            }
                        })
                            .promise()
                            .then(data => {
                                console.log(`Successfully uploaded ${event.path}`);
                                callback(null, {
                                    modified: modified,
                                    removed: removed
                                });
                            })
                            .catch(err => {
                                callback(err);
                            });
                    });
            })
                .catch(err => {
                    callback(err);
                });
        })
        .catch(err => {
            callback(err);
        });
}
//function that should return my base64 encoded image
function base64_encode(path,file,thebase) {
    var leKey = path+'/'+file;
    var params = {
    'Bucket': "xxx",
        'Key': leKey
    }
   s3.getObject(params, function(error, data) {
        console.log('error: '+error);
     	}).promise().then(data => {
        	thebase = data.Body.toString('base64');
        	console.log('thebase: '+thebase); //<- here I see the base64 encoded string
        	return thebase; //<- does not return thebase
       });
      return thebase; //<- does not return thebase
}

1 个答案:

答案 0 :(得分:0)

这是一个与承诺相关的问题,函数“ return thebase”中的最后一个调用;由于承诺尚未解决,很可能会返回不确定的状态。函数返回时。我发现使用关键字async并等待它确实将代码简化为更具可读性的格式(使代码更加平整)很有用。

function base64_encode(path,file,thebase) {
  var leKey = path+'/'+file;
  var params = {
    'Bucket': "xxx",
    'Key': leKey
  }
  return s3.getObject(params).promise();
}

然后在要使用.then()

处理承诺的主函数中

如果您使用的是异步/等待,则如下所示:

async function base64_encode(path,file,thebase) {
  var leKey = path+'/'+file;
  var params = {
    'Bucket': "xxx",
    'Key': leKey
  }
  return s3.getObject(params).promise();
}

let thebase = await base64_encode('stuff');

希望这会有所帮助