Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 如何将forEach与承诺结合起来_Node.js_Mongodb_Promise - Fatal编程技术网

Node.js 如何将forEach与承诺结合起来

Node.js 如何将forEach与承诺结合起来,node.js,mongodb,promise,Node.js,Mongodb,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 (e

我正在做一个函数,将图像从输入文件字段上传到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
 },
不是每次循环遍历元素时都保存到数据库,我只是填充一个数组图像,然后将其保存到DB。

为此,您希望使用而不是。这是因为您打算将一些值映射到基于每个值的承诺

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中没有内置的承诺支持,那么可以使用promisify实用程序,比如用适配器包装函数,该适配器将根据回调的结果为您创建承诺

资源 为此,您希望使用而不是。这是因为您打算将一些值映射到基于每个值的承诺

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中没有内置的承诺支持,那么可以使用promisify实用程序,比如用适配器包装函数,该适配器将根据回调的结果为您创建承诺

资源 你可以用蓝鸟来做你的 uploadToAWS返回承诺而不是接受回调您也可以在不使用promisify的情况下轻松地执行此操作,但它很有用,因为如果您要使用promise.all等,则使用返回承诺的函数要容易得多。如果您要使用接受回调的函数,我建议使用模块来管理控制流

当您承诺上传到AWS时,您将能够执行以下操作:

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
}
现在,无论何时你有IMG,它都是一个由uploadToAWS返回的对象数组,或者严格地说,是一个由uploadToAWS返回的承诺的解析值数组,在所有这些承诺都已解析之后

您可以使用该阵列创建另一个类似图像的阵列:

或:

取决于uploadToAWS实际返回的内容,因为您没有指定

但请记住,当您出现错误时,您需要通过删除已上载的不再需要的文件来恢复错误。

您可以使用Bluebird's来进行恢复 uploadToAWS返回承诺而不是接受回调您也可以在不使用promisify的情况下轻松地执行此操作,但它很有用,因为如果您要使用promise.all等,则使用返回承诺的函数要容易得多。如果您要使用接受回调的函数,我建议使用模块来管理控制流

当您承诺上传到AWS时,您将能够执行以下操作:

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
}
现在,无论何时你有IMG,它都是一个由uploadToAWS返回的对象数组,或者严格地说,是一个由uploadToAWS返回的承诺的解析值数组,在所有这些承诺都已解析之后

您可以使用该阵列创建另一个类似图像的阵列:

或:

取决于uploadToAWS实际返回的内容,因为您没有指定


但是请记住,当您出现错误时,您需要通过删除已上载的不再需要的文件来恢复错误。

这不是最好的办法。如果出现错误,S3上的孤立文件在数据库中没有任何引用。这不是最好的主意。如果出现错误,您将在S3上拥有孤立文件,而数据库中没有任何引用。使用.map的问题是,如果用户仅上载一个图像,则map失败,但如果用户上载多个.map工作正常。。。原因是对于多个文件,它发送一个对象数组,但是对于单个文件,它只发送一个对象。使用.map的问题是,如果用户只上载一个图像,则map失败,但是如果用户上载多个.map,则可以正常工作。。。原因是对于多个文件,它发送一个对象数组,但是对于单个文件,它只发送一个对象。