简体   繁体   English

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

[英]NodeJS - Return a single status code from an async function using Array.protoype.map() to save multiple files in different locations in a database

I am a little stumped on how to handle this the best way possible.我对如何以最好的方式处理这个问题感到有些困惑。 I've decided to rewrite this controller, and I need to (at least I think) make use of promise.all() here.我决定重写这个控制器,我需要(至少我认为promise.all()在这里使用promise.all()

Premise:前提:

In this application, the Admin user must be able to bulk upload a bunch of .pdf's at once that are for multiple users.在此应用程序中,管理员用户必须能够一次批量上传一组供多个用户使用的 .pdf 文件。 The .pdf's adhere to a specific naming convention that my backend upload controller by using a regEx , pulls out a first and last name. .pdf 遵循特定的命名约定,我的后端上传控制器使用regEx提取名字和姓氏。 These .pdf's are auto-generated in a program, that always names them exactly the same, so there is no human error in misspelling names.这些 .pdf 是在程序中自动生成的,它们的名称始终完全相同,因此不会出现拼写错误的人为错误。

Each call to the database and an AWS S3 Bucket is made within an Array.prototype.map() a function that is looping through and uploading a file to an S3 bucket, and then it takes the Key name of the file returned from s3.upload() and saves that Key to a user model in Mongo DB as a reference to their file(s) within the S3 Bucket.对数据库和 AWS S3 存储桶的每次调用都在Array.prototype.map()函数中进行,该函数循环遍历并将文件上传到 S3 存储桶,然后获取从s3.upload()返回的文件的Key名称s3.upload()并将该Key保存到 Mongo DB 中的用户模型中,作为对其在 S3 存储桶中的文件的引用。

Example Code:示例代码:

This is what I currently have (that does work somewhat).这就是我目前所拥有的(确实有些作用)。 This is the block of code responsible for what I described above.这是负责我上面描述的代码块。 employeeFiles is created further up in the controller and contains an array of objects that each have a file and id property. employeeFiles是在控制器中进一步创建的,它包含一个对象数组,每个对象都有一个fileid属性。 The file name destructuring and user matching happen further up in the controller as well, and the employeeFiles array is a result of that.文件名解构和用户匹配也发生在控制器的更上方, employeeFiles数组是其结果。 The id property contains the mongo _id of the employee, and the file property contains the file to be saved. id属性包含员工的mongo _idfile属性包含要保存的文件。 This all works perfectly, and I don't think that code is needed for context here.这一切都很完美,我认为这里的上下文不需要代码。 fileType is a variable available within the scope of the controller: 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));
      }
    });
  });
};

I am making use of next() to handle any errors within the s3.upload() and findOneAndUpdate() functions (I do realize findOneAndUpdate() is deprecated) moving forward.我正在使用next()来处理s3.upload()findOneAndUpdate()函数中的任何错误(我确实意识到findOneAndUpdate()已被弃用)向前推进。 My idea here is that if there is an error with one of the functions, next() will send it to my error handler middleware and keep going, versus ending the process and halting all of it.我的想法是,如果其中一个函数出现错误, next()会将其发送到我的错误处理程序中间件并继续运行,而不是结束进程并停止所有进程。

Inside of every iteration of s3.upload() , I make a call to my database so that I can save the reference to the file uploaded to the S3 Bucket .s3.upload()的每次迭代中,我都会调用我的数据库,以便我可以保存对上传到S3 Bucket的文件的引用。 Inside of a then() method of Employee.findOneAndUpdate() , I return a (200) response to let my client know everything has been uploaded to S3 and saved in my DB.Employee.findOneAndUpdate()then()方法中,我返回一个(200)响应,让我的客户知道所有内容都已上传到 S3 并保存在我的数据库中。 So on each iteration of this map() function, I am returning a 200. If I have 10 files, I am returning 200 10 times.所以在这个map()函数的每次迭代中,我返回 200。如果我有 10 个文件,我将返回 200 10 次。

I feel that I can convert this into an async function, and make use of a promise.all() to return a single status code upon completion.我觉得我可以将其转换为async函数,并在完成时使用promise.all()返回单个状态代码。 Returning that many status codes seem a bit crazy to me.返回这么多状态代码对我来说似乎有点疯狂。 But I am not too sure how to approach this while using a map() function to loop and make an async call on every iteration.但是我不太确定如何在使用map()函数循环并在每次迭代时进行异步调用时解决这个问题。

Hope this makes sense, and thank you in advance for looking at this!希望这是有道理的,并提前感谢您查看此内容!

I would split it up into a 2-step process.我会把它分成一个两步的过程。 Upload in bulk and then save to mongo if it all worked out.批量上传,如果一切顺利,然后保存到 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
  })
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在对象数组上使用Array.protoype.map()来基于其值过滤掉某些特定键? - How to use Array.protoype.map() on array of objects to filter out some specific keys based on it's values? NodeJS:从循环中的多个TSV文件异步返回数据 - NodeJS: Async return data from multiple TSV files in loop 如何从javascript中的array.map中的异步函数返回一个值? - How to return a value from a async function in array.map in javascript? 如何从Array.map()函数正确返回异步数据 - How to properly return async data from Array.map() function 从不同位置上传多个文件 - Upload multiple files from different locations 使用 array.protoype.forEach (javascript) 创建多个按钮 - Create multiple buttons using array.protoype.forEach (javascript) NodeJS: map function 将返回一个空数组 - NodeJS: map function will return an empty array 如何从 async.map() function 返回数据? - How to return data from an async .map() function? 通过“ this”返回“不是函数”的原型调用函数 - protoype call function via “this” return “is not a function” 在数组映射函数中将类的`this`对象与async,await一起使用-Node.js,Javascript - Use `this` object of the class in array map function with async, await - Nodejs, Javascript
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM