我正在执行一个功能,该功能可从输入文件字段将图像上传到AWS,然后将图像URL和名称保存到mongoDB。我正在使用NodeJS和MongoDB。这是我的示例:
uploadFile(req, res, next) {
let files = req.files;
let images = [];
files.file.forEach((file) => {
uploadToAWS(file.path, {}, function(err, img) {
if (err) { throw err; }
// add path and name to images array
images.push({
path: img[0].url,
name: img[0].name,
});
});
});
// Here the promises should resolve and save to MongoDB the array images
},
每次循环遍历元素时,我没有填充到数据库,而是填充了数组
images
,然后将其保存到DB。 最佳答案
您可以使用Bluebird的promisify
uploadToAWS()
返回承诺而不是进行回调(您也可以在没有promisify
的情况下很容易地做到这一点,但是它很有用),因为如果要使用Promise.all等,使用返回承诺的函数要容易得多。建议使用回调的函数,然后建议使用Async模块来管理控制流。
当您分配uploadToAWS()
时,您将可以执行以下操作:
let promises = files.file.map(file => uploadToAWS(file.path, {}));
然后,您将可以使用:
Promise.all(promises)
.then((imgs) => {
// everything succeeded
}).catch((error) => {
// there was an error
});
或者,如果您使用的是异步/等待:
try {
let imgs = await Promise.all(promises);
// everything succeeded
} catch (error) {
// there was an error
}
现在,只要有
imgs
,它就是uploadToAWS()
返回的对象数组(或者严格地说,是在所有元素都已解析后由uploadToAWS()
返回的承诺的分辨率值数组)。您可以使用该数组创建另一个数组,例如
images
:let images = imgs.map(img => ({
path: img[0].url,
name: img[0].name,
});
要么:
let images = imgs.map(img => ({
path: img.url,
name: img.name,
});
取决于
uploadToAWS()
实际返回的内容,因为您未指定。但是请记住,发生错误时,您将需要通过删除不再需要的上传文件来从中恢复。