如何仅在将两个图像都保存到存储后才将图像链接上传到数据库

时间:2021-07-22 16:57:57

标签: node.js express mongoose google-cloud-storage multer

我正在为这个项目使用 MERN 堆栈、multer、mongoose 和谷歌云存储。为简单起见,我使用更简单的代码来反映我面临的问题。

在本例中,req.files 是一个包含 2 个图像的数组,将被放入存储中。

console.log(req.files)  

//output ->  [

//    { fieldname: 'image1',
//    originalname: 'image1.jpg',
//    encoding: '7bit',
//    mimetype: 'image/jpeg',
//    buffer:
//     <Buffer ff d8 ff e2 0b f8 49 43 43 5f 50 52 4f 46 49 4c 45 00 01 01 00 00 0b e8 00 00 00 00 02 00 00 00 6d 6e 74 72 52 47 42 20 58 59 5a 20 07 d9 00 03 00 1b ... >,
//    size: 96807 },

//    { fieldname: 'image2',
//    originalname: 'image2.jpg',
//    encoding: '7bit',
//    mimetype: 'image/jpeg',
//    buffer:
//     <Buffer ff d8 ff e2 0b f8 49 43 43 5f 50 52 4f 46 49 4c 45 00 01 01 00 00 0b e8 00 00 00 00 02 00 00 00 6d 6e 74 72 52 47 42 20 58 59 5a 20 07 d9 00 03 00 1b ... >,
//    size: 96807 }

 ]

const { Storage } = require('@google-cloud/storage');
const storage = new Storage({
    projectId: process.env.GCLOUD_PROJECT_ID,
    keyFilename: process.env.GCLOUD_APPLICATION_CREDENTIALS,
});
const bucket = storage.bucket(process.env.GCLOUD_STORAGE_BUCKET_URL);


exports.blog_post = async (req, res, next) => {

// I am trying to loop through req.files and save them to the storage
  req.files.map(image => {
    const blob = bucket.file(image.originalname);
    const blobWriter = blob.createWriteStream({
      metadata: {
        contentType: image.mimetype,
      },
    });
    blobWriter.on('error', (err) => next(err));
    blobWriter.on('finish', () => {
      if (file.fieldname === "image1") {
        const link1 = `https://firebasestorage.googleapis.com/v0/b/${bucket.name}/o/${encodeURI(blob.name)}?alt=media`;
      } else {
        const link2 = `https://firebasestorage.googleapis.com/v0/b/${bucket.name}/o/${encodeURI(blob.name)}?alt=media`;
      }
    let gallery = new Gallery({
        image1: link1,
        image2: link2
    })
    blog
    .save()
    .then(result => {
      res.status(201).json({
        message: `successful`,
        })
    })
    .catch(err => {
        res.status(500).json({
            error: err
        });
    })
  })
    blobWriter.end(image.buffer);
  })

上面的代码在我的数据库中生成了 2 个查询,这不是我想要的。我想要的是先等待两个图像上传完成,然后才在 1 个查询中放入数据库。我需要类似 Promise.all() 的东西,但我不知道我能做什么。

已编辑*** 我试过这个:

exports.blog_post = (req, res, next) => {
  const image1promise = new Promise((resolve, reject) => {
    req.files.map(image => {
      if (image.fieldname === "image1") {        
        const blob = bucket.file(image.originalname);
        const blobWriter = blob.createWriteStream({
          metadata: {
            contentType: image.mimetype,
          },
        });
        blobWriter.on('error', (err) => next(err));
        blobWriter.on('finish', () => {
            const coverImageLink = `https://firebasestorage.googleapis.com/v0/b/${bucket.name}/o/${encodeURI(blob.name)}?alt=media`;
          // if (file.fieldname === "blogImage") {
          //   const image1link = `https://firebasestorage.googleapis.com/v0/b/${bucket.name}/o/${encodeURI(blob.name)}?alt=media`;
          // }
      })
        blobWriter.end(image.buffer);
        resolve(image1link);
      }
    })
  });

  const image2promise = new Promise((resolve, reject) => {
    req.files.map(image => {
      if (image.fieldname === "image2") {        
        const blob = bucket.file(image.originalname);
        const blobWriter = blob.createWriteStream({
          metadata: {
            contentType: image.mimetype,
          },
        });
        blobWriter.on('error', (err) => next(err));
        blobWriter.on('finish', () => {
            const image2link = `https://firebasestorage.googleapis.com/v0/b/${bucket.name}/o/${encodeURI(blob.name)}?alt=media`;
          // if (image.fieldname === "blogImage") {
          //   const image2link = `https://firebasestorage.googleapis.com/v0/b/${bucket.name}/o/${encodeURI(blob.name)}?alt=media`;
          // }
      })
        blobWriter.end(image.buffer);
        resolve(blogImageLink);
      }
    })
  });

  Promise.all([image1promise, image2promise])
    .then((image1link, image2link) => {
        let blog = new Blog({
            image1: image1link,
            image2: image2link,
        })
        blog
        .save()
        .then(result => {
          res.status(201).json({
            message: `ok`,
            })
        })
        .catch(err => {
            res.status(500).json({
                error: err
            });
        })
    })

1 个答案:

答案 0 :(得分:0)

我已经找到了解决上述尝试的方法!

我没有在 then 中包含 2 个参数,而是将其设为一个,因为 Promise 返回的是一组链接。

我的尝试

Promise.all([image1promise, image2promise])
    .then((image1link, image2link) => {
        let blog = new Blog({
            image1: image1link,
            image2: image2link,
        })

解决方案

Promise.all([image1promise, image2promise])
    .then((imageLinks) => {
        let blog = new Blog({
            image1: imageLinks[0],
            image2: imageLinks[1],
        })

希望能帮到和我有类似问题的朋友

相关问题