如何将 forEach 与 Promises.all 结合使用

Mat*_*att 1 mongodb node.js promise

我正在执行一个函数,将图像从输入文件字段上传到 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
 },
Run Code Online (Sandbox Code Playgroud)

每次循环遍历元素时都没有保存到数据库中,我只是填充一个数组images,然后将其保存到数据库中。

Set*_*day 5

为此,您需要使用Array#map()而不是Array#forEach。那是因为您打算根据这些值中的每一个将一些值映射到承诺。

return Promise.all(files.map((file) => {
    // do some stuff with each file here
}));
Run Code Online (Sandbox Code Playgroud)

一个完整的例子看起来像这样:

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);
}
Run Code Online (Sandbox Code Playgroud)

请注意,在这里,我假设 uploadToAws()能够返回一个承诺,因为这是完成这项工作所必需的,否则房子承诺崩溃了。如果没有对来自 的承诺的内置支持uploadToAws(),您可以使用像pify这样的promisify实用程序将函数包装在一个适配器中,该适配器将根据回调的结果为您创建一个承诺。

资源