[英]Unzipping file and uploading to S3
節點上的路由采用一個 zip 文件,然后我將其解壓縮到內存中並將其上傳到 S3 存儲桶。 一切正常,但在 zip 文件中的所有文件都完成后,我正在努力解決。
function unzipAndUploadToS3(fileInfo) {
return new Promise((resolve, reject) => {
fs.createReadStream(fileInfo.zip.path)
.pipe(unzipper.Parse())
.pipe(etl.map(entry => {
if (checkEntry(entry.path)) {
fileInfo.name = entry.path;
entry
.buffer()
.then(content => {
fileInfo.data = content;
AWS.uploadToS3(fileInfo).then(result => {
console.log(result.Location);
resolve(result.Location); //ALWAYS Resolves here
}).catch(err => {
console.error(err);
reject(err);
})
})
}
else
entry.autodrain();
}))
});
}
我已經嘗試過 Promise.all 和 Async/Await,但似乎可以理解它。
我以前從未使用過etl
,但他們的文檔有一條評論說
從流切換到承諾鏈......
然后給出代碼.promise().then(...)
。 你說你嘗試過Promise.all
,但你沒有說如何,所以我不知道你是否已經嘗試過這個。 但這是我認為事情可能會發展的方向:
function unzipAndUploadToS3(fileInfo) {
return new Promise((resolve, reject) => {
fs.createReadStream(fileInfo.zip.path)
.pipe(unzipper.Parse())
.pipe(etl.map(entry => {
if (checkEntry(entry.path)) {
fileInfo.name = entry.path;
return entry.buffer() //<- return promise
.then(content => {
fileInfo.data = content;
return AWS.uploadToS3(fileInfo) //<- return promise
})
}
else
entry.autodrain();
}))
.promise().then(awsPromises => Promise.all(awsPromises)) //<- return promise
.then(x => resolve('x should be an array of s3 results'))
.catch(err => reject(err));
});
}
為此,盡管所有承諾都需要正確鏈接在一起以進行條目緩沖,然后上傳到 s3。 我標記了重要的回報以保持與評論的鏈接。
還有一些對我來說有點不對勁的東西:我不敢相信你能夠像這樣對多個文件重復使用相同的文件fileInfo
。 對我來說看起來像是一個競爭條件:在下一個文件覆蓋fileInfo.data
和fileInfo.name
之前,上一個上傳會完成嗎? 我的猜測是您最好在地圖內創建一個新的 fileInfo 對象,而不是對 zip 中的所有文件重復使用相同的對象。
這就是最終為我工作的內容。 這使用解壓縮器、etl 和 lodash。
function unzipAndUploadToS3(fileInfo) {
return new Promise((resolve, reject) => {
var filesToProcess = [];
var filesStream = fs.createReadStream(fileInfo.zip.path)
.pipe(unzipper.Parse())
.pipe(etl.map(entry => {
if (checkEntry(entry.path)) {
fileInfo.name = entry.path.substr(entry.path.indexOf('/') + 1, entry.path.length);
entry
.buffer()
.then(content => {
fileInfo.data = content;
var newObj = _.clone(fileInfo); //need to clone object because of object reference in assignment
var promise = new Promise(function(resolve, reject) { //create new promise to upload to S3
AWS.uploadToS3(newObj).then(result => { //a function in another module uses aws-sdk
resolve(result)
}).catch(err => reject(err));
})
filesToProcess.push(promise); //push this promise into an array of promises
})
}
else
entry.autodrain();
}))
filesStream.on('readable', function () { console.log('readable'); })
.on('data', function (data) { console.log('data', data); })
.on('error', function (err) {
console.error('Error', err);
reject(err);
})
.on('end', function () {
Promise.all(filesToProcess).then(values => { //process all the promises
console.log("values>", values);
resolve(values);
}).catch(err => {reject(err)});
})
});
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.