NodeJS - 使用 Array.protoype.map() 从异步函数返回单个状态代码,以将多个文件保存在数据库中



我有点困惑如何以最好的方式处理这个问题。我决定重写这个控制器,我需要(至少我认为(在这里使用promise.all()

前提:

在此应用程序中,管理员用户必须能够一次批量上传一堆供多个用户使用.pdf。.pdf遵循特定的命名约定,即我的后端上传控制器使用regEx提取名字和姓氏。这些.pdf是在程序中自动生成的,该程序始终将它们命名为完全相同的名称,因此拼写错误的名称不会人为错误。

对数据库和 AWS S3 存储桶的每次调用都是在一个Array.prototype.map()函数中进行的,该函数循环访问文件并将其上传到 S3 存储桶,然后获取从s3.upload()返回的文件的Key名称,并将该Key保存到 Mongo DB 中的用户模型中,作为对 S3 存储桶中文件的引用。

示例代码:

这就是我目前拥有的(确实有些工作(。这是负责我上面描述的代码块。employeeFiles在控制器中进一步创建,并包含一个对象数组,每个对象都有一个fileid属性。文件名解构和用户匹配也发生在控制器的更靠前的位置,employeeFiles数组就是由此产生的。id属性包含雇员的mongo _idfile属性包含要保存的文件。这一切都完美地工作,我认为这里的上下文不需要代码。fileType是控制器范围内可用的变量:

const employeeFileUploadToDb = () => {
employeeFiles.map((employee, i) => {
const { file, id } = employee;
const params = {
Bucket: S3_BUCKET_NAME,
Body: file.buffer,
Key: `${filetype}/${file.originalname}`
};
s3.upload(params, (err, data) => {
if (err) {
next(err);
}
if (data) {
//Save reference to Employee model
let dataObj = {
key: data.key,
fileName: file.originalname,
date: Date.now()
};
Employee.findOneAndUpdate(
{ _id: id },
{ $push: { [`${filetype}`]: dataObj } }
)
.then(resp => res.send(200))
.catch(err => next(err));
}
});
});
};

我正在利用next()来处理s3.upload()findOneAndUpdate()函数中的任何错误(我确实意识到findOneAndUpdate()已被弃用(向前发展。我的想法是,如果其中一个函数出错,next()会将其发送到我的错误处理程序中间件并继续运行,而不是结束该过程并停止所有操作。

s3.upload()的每次迭代中,我都会调用我的数据库,以便我可以保存对上传到S3 Bucket的文件的引用。在then()Employee.findOneAndUpdate()方法中,我返回一个(200)响应,让我的客户端知道所有内容都已上传到 S3 并保存在我的数据库中。因此,在这个map()函数的每次迭代中,我都会返回 200。如果我有 10 个文件,我将返回 200 10 次。

我觉得我可以将其转换为async函数,并利用promise.all()在完成后返回单个状态代码。返回这么多状态代码对我来说似乎有点疯狂。但是我不太确定在使用map()函数在每次迭代时循环并进行异步调用时如何处理这个问题。

希望这是有道理的,并提前感谢您查看此内容!

我会把它分成一个两步过程。批量上传,如果一切顺利,则保存到 mongo。

const employeeFileUploadToDb = () => {
const uploadFiles = files => files.map((employee, i) => new Promise((resolve, reject) => {
//...
s3.upload(params, (err, data) => {
if (err) {
return reject(err);
}
resolve(data);
})
});
});

Promise.all(uploadData(employeeFiles)).then((err, data) => {
// Handle saving to mongo
})
};

最新更新