我正在执行一个函数,该函数将图像从输入文件字段上传到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
然后将其保存到数据库。
为此,您希望使用 Array#map() 而不是 Array#forEach。这是因为您打算根据每个值将某些值映射到承诺。
return Promise.all(files.map((file) => {
// do some stuff with each file here
}));
一个完整的示例如下所示:
uploadFile(req, res, next) {
let files = req.files;
let images = [];
const promises = files.file.map((file) => {
return uploadToAWS(file.path, {}).then((img) => {
// 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
Promise.all(promises).then(next);
}
请注意,在这里,我假设uploadToAws()
能够返回一个承诺,因为这是完成这项工作所必需的,否则
uploadToAws()
承诺支持,您可以使用像 pify 这样的promisify实用程序将函数包装为适配器,该适配器将根据回调的结果为您创建承诺。
资源
- http://2ality.com/2014/10/es6-promises-api.html
- http://2ality.com/2016/10/async-function-tips.html
您可以使用Bluebird的promisify
来制作您的uploadToAWS()
返回一个承诺而不是接受回调(你也可以在没有promisify
的情况下轻松做到这一点,但它很有用),因为如果你想使用 Promise.all 等,使用返回承诺的函数要容易得多。如果要使用接受回调的函数,那么我建议使用异步模块来管理控制流。
当你承诺你的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()
实际返回的内容,因为您没有指定。
但请记住,当您遇到错误时,您需要通过删除不再需要的上传文件来从中恢复。