[英]Upload images to MongoDB after compressing and delete images from the Multer uploads directory
我對開發相關的工作非常陌生。 請幫忙
我正在嘗試將用戶拍攝的 10 張圖像(通過 MULTER 實現)上傳到 mongoDB 數據庫,但是,在最終上傳之前,我想使用 SHARP 壓縮圖像。
我嘗試使用回調來做到這一點。 但是失敗了。
這就是我想要做的:
UPLOADS/IMAGES
目錄。.jpeg
文件存儲到UPLOADS/COMPRESSED
目錄。然后
fsPromises.readFile
讀取UPLOADS/COMPRESSED
目錄中新壓縮的圖像。然后
const toInsertImgData = { data: result, contentType: "image/jpeg"};
imgArray
的數組中。 這里的result
是上一步中讀取的二進制數據。然后
fsPromises.unlink
刪除UPLOADS/IMAGES
和UPLOADS/COMPRESSED
中的所有文件然后
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);
});
});
在每個內部,您使用異步調用,這意味着 all.then() 保證在 before.forEach 結束之前執行,因此 promises 數組可能是模棱兩可的。 一個簡單的解決方法是使用 fs.promises inside.then() 而不是將其推送到 Promise 中。
下面是一個非常相似的用例,可能有助於解決上述問題。 我提供了完整的 API 路由代碼以便更好地理解它。
var fs = require('fs');
var path = require('path');
const sharp = require('sharp');
const multer = require('multer');
var storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, './public/uploads')
},
filename: (req, file, cb) => {
cb(null, file.fieldname + '-' + Date.now())
}
});
var upload = multer({ storage: storage });
app.post('/imageupload', upload.single('image'), async (req, res, next) => {
console.log("Image post request by " + req.user.username);
await sharp('./public/uploads/' + req.file.filename).resize(150, 150)
.rotate()
.png({ quality: 100 }).toFile('./public/uploads/' + req.file.filename + '-thumb');
Member.findOneAndUpdate({ sabhe_id: req.body.sabhe_id },
{
img: {
data: fs.readFileSync(path.join('./public/uploads/' + req.file.filename + '-thumb')),
contentType: 'image/png'
}
}
, function (err) {
if (err) {
console.log(err.message);
}
else {
console.log("Image saved to database " + req.user.username);
fs.unlink('./public/uploads/' + req.file.filename, (err) => {
if (err) {
console.error(err.message);
return
}
});
fs.unlink('./public/uploads/' + req.file.filename + '-thumb', (err) => {
if (err) {
console.error(err.message)
return
}
});
if (req.user.isAdmin) {
res.redirect("/admin")
} else {
res.redirect("/profile");
}
}
}
)
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.