我正在开发MEAN堆栈应用程序,并且正在使用AWS开发工具包将多个文件上传到S3。我正在使用busboy和AWS开发工具包。

码:

var inputObj = {};
 var busboy = new Busboy({ headers: req.headers });
    // The file upload has completed
    busboy.on('finish', function() {
     console.log('Upload finished.....');
     var file = [];
     const file1 = req.files.clogo;
     const file2 = req.files.cbanner1;
     const file3 = req.files.cbanner2;
     const file4 = req.files.cbanner3;
     const file5 = req.files.cbanner4;
     const file6 = req.files.clongHeader;
     file.push(file1);
     file.push(file2);
     file.push(file3);
     file.push(file4);
     file.push(file5);
     file.push(file6);
     multipleUploadToS3(req.body.cname, file, function(fileName) {
            console.log("client file upload finished.....");
             if(fileName.length == 6){
                inputObj.clogo = fileName[0];
                inputObj.cbanner1 = fileName[1];
                inputObj.cbanner2 = fileName[2];
                inputObj.cbanner3 = fileName[3];
                inputObj.cbanner4 = fileName[4];
                inputObj.clongHeader = fileName[5];

                console.log(inputObj);
                var clientObj = new client(inputObj);
                clientObj.save(function(err, client) {
                    console.log("Client Saved.....");
                    if (err) {
                        return res.status(400).send({
                            message: errorHandler.getErrorMessage(err)
                        });
                    } else {
                        res.json(client);
                    }
                });
             }
     });
    });
    req.pipe(busboy);


文件上传方式:

function multipleUploadToS3(client, file, callback) {
    console.log("multipleUpload to S3");
    console.log(client);
    console.log(file);

    let s3bucket = new AWS.S3({
        accessKeyId: IAM_USER_KEY,
        secretAccessKey: IAM_USER_SECRET,
        Bucket: BUCKET_NAME,
    });

    var fileNames = [];

    for(var i=0; i<file.length; i++){
        s3bucket.createBucket(function () {
            var params = {
            Bucket: BUCKET_NAME,
            Key: client+ '/' + file[i].name,
            Body: file[i].data,
            };
            s3bucket.upload(params, function (err, data) {
                if (err) {
                    console.log('error in callback');
                    console.log(err);
                }
                console.log('success');
                //console.log(data.key);
                fileNames.push(data.key);
                if(i == file.length){ callback(fileNames);}
            });
        });
    }

};


问题:文件上传是异步的,因此例如,如果我正在上传的file1是诚实.jpg,那么我希望multipleUploadToS3方法在将文件上传到S3之后返回文件名。我将其绑定到inputObj键中,该键将保存到mongo db。因此inputObj.logo中应该有logo.png而不是由于异步调用而发生的横幅图像。

这适用于单个文件,但不适用于多个文件。

最佳答案

问题是因为for循环是同步的,文件上传是异步的。

看下面的这个例子,

for(var i = 0; i<5;i++) {
  setTimeout(function(){ console.log(i); }, 100);
}


上面的循环将打印5次5次,即55555。

此行为是因为for循环立即执行,使i = 5,并且执行超时时,它会打印5次“ i”值5。 5次,因为setTimeout在队列中被推送了5次。

有两种方法可以解决您面临的问题


您可以使用递归。
使用neo-async(async-parallel)库控制javascript(Nodejs)的异步流程。 click here for neo-async lib


希望这能消除您的疑问。请发表评论以获取更多信息。

07-24 09:39
查看更多