Загружать изображения в MongoDB после сжатия и удаления изображений из каталога загрузки Multer.

Я очень новичок в работе, связанной с развитием. ПОЖАЛУЙСТА, ПОМОГИТЕ

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

Я пытался сделать это с помощью обратных вызовов. Но НЕУДАЧНО.

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

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

ПОТОМ

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

ПОТОМ

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

ПОТОМ

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

ПОТОМ

  1. Используйте 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);
    });
});

person dewesh jha    schedule 06.08.2020    source источник


Ответы (1)


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

person AnonyMouze    schedule 06.08.2020