我从这里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
}
答案 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');
希望这会有所帮助