最大化您的上传效率:如何使用node.js和Cloudinary执行并行文件上传
#javascript #网络开发人员 #node #cloudinary

在我最近的一个项目中,我正在研究这个非常酷的事情,称为订单管理系统(OMS)。基本上,正是这个集中式平台可以帮助非政府组织自动化各种东西 - 例如管理他们的程序,应用程序,员工,学生,志愿者,电子邮件,文件和表格。

无论如何,在项目的某个时刻,我必须弄清楚如何处理特定端点的文件上传到云。我的最初解决方案奏效了,但是有点慢 - 一次上传五个文件大约需要一段时间。作为开发人员,我知道我可以做得更好,所以我想出了一个新的解决方案,该解决方案更快地工作。

如果您正在使用Multer,这是一个非常方便的工具,用于在Node.js中上传文件,则可以使用它将文件上传到Cloudinary:

import cloudinary from "./cloudinary";

const { upload } = cloudinary.uploader;

const uploadFile = async (file: Express.Multer.File) => {
  const uploadedFile = await upload(file.path, {
    folder: "/upload-folder/files",
    public_id: file.fieldname,
    overwrite: true,
  });

  return uploadedFile.secure_url;
};

上传文件后,您可以将结果保存在数据库中。为此,请使用文件的字段名称(例如“ profileImage”)作为键,而secure_url作为值。

但是,有时您可能需要一次上传多个文件。例如,如果您在页面上有三个文件上传输入,并且其中一个可以让用户上传最多三个文件,则必须处理总共五个文件。在这种情况下,您可以使用输入的名称属性来识别哪个文件属于。因此,如果用于上传三个文件的输入命名为“ supportingDocuments”,其他两个输入命名为“ profileImage”和“简历”,则可以使用这些名称来跟踪哪些文件已上传到位置。

以上提到的三个文件输入,这是req.files的外观示例:

[
  {
    "fieldname": "supportingDocuments",
    "originalname": "document1.pdf",
    "encoding": "7bit",
    "mimetype": "application/pdf",
    "size": 1234567,
    "buffer": "<Buffer 25 50 44 46 2d 31 2e 33 ... >"
  },
  {
    "fieldname": "supportingDocuments",
    "originalname": "document2.jpg",
    "encoding": "7bit",
    "mimetype": "image/jpeg",
    "size": 345678,
    "buffer": "<Buffer ff d8 ff e0 00 10 ... >"
  },
  {
    "fieldname": "supportingDocuments",
    "originalname": "document3.docx",
    "encoding": "7bit",
    "mimetype": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
    "size": 987654,
    "buffer": "<Buffer 50 4b 03 04 0a 00 ... >"
  },
  {
    "fieldname": "profileImage",
    "originalname": "profile.jpg",
    "encoding": "7bit",
    "mimetype": "image/jpeg",
    "size": 234567,
    "buffer": "<Buffer ff d8 ff e0 00 10 ... >"
  },
  {
    "fieldname": "resume",
    "originalname": "resume.pdf",
    "encoding": "7bit",
    "mimetype": "application/pdf",
    "size": 876543,
    "buffer": "<Buffer 25 50 44 46 2d 31 2e 33 ... >"
  }
]

因此,如果我们在“ supportingDocuments”字段中上传了三个文件,并且在“ profileImage”和“ recume”字段中每个文件中每个文件,我们如何上传这些文件并将结果保存在数据库中?

这是:

import { UploadApiResponse } from "cloudinary";
import cloudinary from "./cloudinary";

type Files =
  | Express.Multer.File[]
  | { [fieldname: string]: Express.Multer.File[] };

async function uploadFiles(
  files: Files
): Promise<{ [key: string]: string | string[] }> {
  if (!Array.isArray(files)) return {};

  const results: { [key: string]: string | string[] } = {};
  const fieldNames: string[] = [];
  const fieldNamesOccurrences: { [fieldname: string]: number } = {};

  const uploads = files.map((file, i) => {
    fieldNames.push(file.fieldname);

    return cloudinary.uploader.upload(file.path, {
      folder: "/upload-folder/files",
      public_id: file.fieldname + i,
      overwrite: true,
    });
  });

  const uploadResults: UploadApiResponse[] = await Promise.all(uploads);

  for (let i = 0; i < fieldNames.length; i++) {
    const fieldName = fieldNames[i];
    const uploadedFile = uploadResults[i];

    fieldNamesOccurrences[fieldName] =
      (fieldNamesOccurrences[fieldName] || 0) + 1;

    if (fieldNamesOccurrences[fieldName] > 1) {
      if (Array.isArray(results[fieldName])) {
        (results[fieldName] as Array<string>).push(uploadedFile.secure_url);
      } else if (typeof results[fieldName] === "string") {
        results[fieldName] = [
          results[fieldName] as string,
          uploadedFile.secure_url,
        ];
      } else {
        results[fieldName] = uploadedFile.secure_url;
      }
    } else {
      results[fieldName] = uploadedFile.secure_url;
    }
  }

  return results;
}

因此,首先,我们需要给uploadFiles函数一个称为文件的参数。 (来自req.files)。这可以是文件数组,也可以是具有字段名称和文件数组的对象。我们在函数中检查一下。

接下来,我们创建一些空的对象和数组,以帮助我们跟踪所有内容。我们有一个称为results的空对象,一个称为fieldNames的空数组,另一个称为fieldNamesOccurrences的空对象。

然后,对于“文件数组”中的每个文件,我们获得了与之关联的字段的名称,并将其添加到fieldNames数组中。我们还使用Cloudinary软件包上传每个文件,然后将上传的承诺推到一个名为uploads的数组。

我们使用一种称为Promise.all()的特殊方法来等待所有文件上传立即完成。这使得过程更快!上传所有文件后,我们将获得一系列uploadapiresponse对象,称为uploadResults

最后,我们循环浏览fieldNames数组,并检查每个字段名称出现多少次。如果看起来不止一次,我们将上传的文件URL添加到与该字段名称关联的结果对象中的数组中。如果仅出现一次,我们简单地将URL设置为与结果对象中该字段名称关联的字符串。

就是这样! uploadFiles函数可帮助您使用Cloudinary上传文件,并返回一个对象,向您显示与每个字段名称关联的上传文件的URL。

真棒新闻对吗?从功能中获得结果后,您可以根据需要将它们保存在数据库中。这意味着您可以上传到Cloudinary并将文件保存在数据库超快中。

这就是所有人ð。喜欢并在评论部分留下您的想法。随时在Twitter上关注我。