Загрузите изображения в MongoDB после сжатия и удалите изображения из каталога загрузок Multer - PullRequest
0 голосов
/ 06 августа 2020

Я новичок в работе, связанной с разработкой. ПОМОГИТЕ

Я пытаюсь загрузить 10 изображений, полученных от пользователя (реализовано через MULTER), в базу данных mongoDB, но перед окончательной загрузкой я хочу сжать изображения с помощью SHARP.

Я пробовал делать это с помощью обратных вызовов. Но НЕ ИСПОЛЬЗУЕТСЯ.

Это то, что я хочу сделать:

  1. использовать MULTER для загрузки массива из 10 изображений в каталог UPLOADS/IMAGES.
  2. ДЛЯ КАЖДОГО файл в массиве используйте SHARP для сжатия файла и сохранения нового сжатого файла .jpeg в каталог UPLOADS/COMPRESSED.

THEN

используйте fsPromises.readFile, чтобы прочитать новое сжатое изображение в каталоге UPLOADS/COMPRESSED.

THEN

создать объект: const toInsertImgData = { data: result, contentType: "image/jpeg"}; и pu sh это в массиве с именем imgArray. Здесь result - это двоичные данные, считанные на предыдущем шаге.

THEN

используйте fsPromises.unlink, чтобы удалить все файлы в UPLOADS/IMAGES и UPLOADS/COMPRESSED

THEN

Используйте imgArray, чтобы создать документ для сохранения в коллекции posts базы данных.

Прямо сейчас каждый раз, когда imgArray пуст, когда я хочу использовать его в конце. Я знаю, что PROMISES или AYSNC / AWAIT могут помочь. Но я не знаю, как это реализовать. Пожалуйста, помогите.

СПАСИБО, ЕСЛИ ВЫ ПРОЧИТАЛИ ЭТО ДАЛЬШЕ

Вот мой код:

const promises = [];
app.post("/compose/:id", upload.array("image", 10), (req, res) => {
  const id = req.params.id;
  const imgArray = [];
  const caption = req.body.caption;
  const now = new Date();

  
  req.files.forEach((file) => {
    const compressedImgPath =__dirname +"/public/uploads/compressed/" +now.getDate() +"-" +(now.getMonth() + 1) +"-" +now.getFullYear() +"-" +now.getTime() +".jpeg";
    sharp(file.path)
      .resize(640, 480)
      .jpeg({
        quality: 80,
        chromaSubsampling: "4:4:4",
      })
      .toFile(compressedImgPath)
      .then(() => {
        fsPromises.readFile(compressedImgPath)
          .then((result) => {
            const toInsertImgData = {
              data: result,
              contentType: "image/jpeg",
            };
            imgArray.push(toInsertImgData);
          })
          .then(() => {
            promises.push(fsPromises.unlink(compressedImgPath));
            promises.push(fsPromises.unlink(file.path));
          })
          .catch((err) => {
            console.log(err);
          });
      });
  });

  Promise.all(promises)
    .then(() => {
      User.findById(id, (err, result) => {
        if (!err) {
          if (imgArray.length > 0) {
            console.log("found user:" + id);
            const newPost = new Post({
              uId: id,
              userName: result.name,
              timeStamp: "5th August, 2020 at 2:10PM",
              caption: caption,
              img: imgArray,
            });
            newPost.save((err) => {
              if (!err) {
                console.log("post saved in DB");
                res.redirect("/users/" + id.toString());
              } else {
                console.log(err);
              }
            });
          } else {
            console.log("array is empty");
          }
        }
      });
    })
    .catch((err) => {
      console.log(err);
    });
});

1 Ответ

0 голосов
/ 06 августа 2020

внутри для каждого, вы используете вызов asyn c, что означает, что все .then () гарантированно будут выполнены до конца .forEach, поэтому массив обещаний может быть неоднозначным. Одно простое решение - использовать fs.promises inside.then (), а не pu sh it для обещаний.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...