javascript - 通过服务器将多个文件上传到 S3 时如何从失败中恢复?

标签 javascript node.js amazon-s3 busboy

刚接触 NodeJS 和 S3,我编写了以下探索性代码,通过 NodeJS 服务器将文件上传到 S3,而不将文件保存到磁盘或内存:

var express = require('express');
var Busboy = require('busboy');
var S3 = require('../utils/s3Util');
var router = express.Router(); // mounted at /uploads

router.post("/", function (req, res, next) {
    let bb = new Busboy({ headers: req.headers });
    const uploads = [];
    bb.on('file', (fieldname, stream, filename, encoding, mimeType) => {
        console.log(`Uploaded fieldname: ${fieldname}; filename: ${filename}, mimeType: ${mimeType}`);
        uploads.push(S3.svc.upload({ Bucket: 'my-test-bucket', Key: filename, Body: stream }).promise());
    });
    bb.on('finish', () => {
        console.log("# of promises:", uploads.length);
        Promise.all(uploads).then(retVals => {
            for (let i = 0; retVals && i < retVals.length; i++) {
                console.log(`File ${i + 1}::`, retVals[i]); 
            }
            res.end();
        }).catch(err => {
            console.log("Error::", err);
            res.status(500).send(`${err.name}: ${err.message}`);
        });
    });
    req.pipe(bb);
});

module.exports = router;

一般失败的情况下,如果有1个或多个x个文件上传失败,该如何处理?有些上传会成功,有些会失败。但是,在 catch 子句中,我不知道哪些失败了......

如果能够使此上传过程有点事务性,那就太好了(即,要么所有上传成功,要么全部上传失败)。当错误发生时,理想情况下我能够“回滚”成功上传的子集。

最佳答案

你可以这样做:

将一个对象推送到上传中,并包含您需要重试的数据,因此:

uploads.push({ 
  fieldname, 
  filename, 
  mimeType,
  uploaded: S3.svc.upload({ Bucket: 'my-test-bucket', Key: filename, Body: stream })
    .promise()
    .then(() => true)
    .catch(() => false)
});

...

const failed = await 
  (Promise.all(uploads.map(async upload => ({...upload, uploaded: await upload.uploaded})))).then(u => u.filter(upload => !upload.uploaded))

const failedFiles = failed.join(', ')

console.log(`The following files failed to upload: ${failedFiles}`);

您需要使事件处理程序异步以在其中使用await,因此,例如:

bb.on('file', async (fieldname, stream, filename, encoding, mimeType) => {

关于javascript - 通过服务器将多个文件上传到 S3 时如何从失败中恢复?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60274050/

相关文章:

javascript - 使用 ObjectController 时,模型中的 Ember.js 数据不会传递到 View

javascript - 如何将此 jquery 代码转换为 noconflict

javascript - Node webkit (nwjs) : how to apply 'new-win-policy' universally?

heroku paperclip 奇怪的错误 Paperclip::Errors::MissingRequiredValidatorError

amazon-s3 - 我们如何使用 serverless.yml 创建 AWS S3 存储桶并向其中添加文件?

javascript - 多个页面需要自动刷新,每个页面上保存不同的选项

类似 Javascript ||在 PHP 中

node.js - Heroku 为具有不寻常文件夹结构的 Node 应用程序构建

node.js:回调顺序困惑

amazon-web-services - Terraform - 启用访问负载平衡器日志 InvalidConfigurationRequest : Access Denied for bucket