簡體   English   中英

解壓文件並上傳到 S3

[英]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.datafileInfo.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM