อัปโหลดภาพไปยัง MongoDB หลังจากบีบอัดและลบภาพออกจากไดเร็กทอรี Multer uploads

ฉันยังใหม่มากกับงานที่เกี่ยวข้องกับการพัฒนา โปรดช่วย

ฉันกำลังพยายามอัปโหลด 10 ภาพที่ถ่ายจากผู้ใช้ (ใช้งานผ่าน MULTER) ไปยังฐานข้อมูล mongoDB แต่ก่อนที่จะอัปโหลดครั้งสุดท้าย ฉันต้องการบีบอัดรูปภาพโดยใช้ SHARP

ฉันลองทำสิ่งนี้โดยใช้การโทรกลับ แต่ล้มเหลว

นี่คือสิ่งที่ฉันต้องการทำ:

  1. ใช้ MULTER เพื่ออัปโหลดอาร์เรย์ 10 ภาพไปยังไดเร็กทอรี UPLOADS/IMAGES
  2. สำหรับแต่ละไฟล์ในอาร์เรย์ ให้ใช้ SHARP เพื่อบีบอัดไฟล์และจัดเก็บไฟล์ .jpeg ที่บีบอัดใหม่ไปยังไดเร็กทอรี UPLOADS/COMPRESSED

แล้ว

  1. ใช้ fsPromises.readFile เพื่ออ่านรูปภาพที่บีบอัดใหม่ในไดเร็กทอรี UPLOADS/COMPRESSED

แล้ว

  1. สร้าง object : const toInsertImgData = { data: result, contentType: "image/jpeg"};
    และผลักมันเข้าไปในอาร์เรย์ชื่อ imgArray ที่นี่ result คือข้อมูลไบนารีที่อ่านในขั้นตอนก่อนหน้า

แล้ว

  1. ใช้ fsPromises.unlink เพื่อลบไฟล์ทั้งหมดใน UPLOADS/IMAGES และ UPLOADS/COMPRESSED

แล้ว

  1. ใช้ imgArray เพื่อสร้างเอกสารเพื่อบันทึกในคอลเลกชัน posts ของฐานข้อมูล

ตอนนี้ทุกครั้งที่ imgArray ว่างเปล่าเมื่อฉันต้องการใช้ในตอนท้าย ฉันรู้ว่า สัญญา หรือ 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)


ภายในสำหรับแต่ละ คุณใช้การโทรแบบ async ซึ่งหมายความว่า .then() ทั้งหมดรับประกันว่าจะดำเนินการก่อน .forEach สิ้นสุด ดังนั้นสัญญาว่าอาร์เรย์อาจไม่ชัดเจน วิธีแก้ไขง่ายๆ อย่างหนึ่งคือใช้ fs.promises inside.then() และไม่ผลักดันให้เป็นไปตามสัญญา

person AnonyMouze    schedule 06.08.2020