问题
I have an input tag to upload multiple images and upload them to cloudinary using cloudinary and formidable packages.
Ideally, i wanted to pull the URL and save it in my DB where i have all the rest information.
But failed to retrieve the URLs shown below in array.
Target it to create an object to be saved in the DB with the URLs.
app.post("/newcampbook",(req,res)=>{
new formidable.IncomingForm({ multiples: true }).parse(req,(err,fields,file)=>{
if(!err){
var pathArray = [];
file.image.forEach(e =>{
pathArray.push(e.path)
})
var savedUrl = [];
pathArray.forEach(e =>{
cloudinary.uploader.upload(e, (err,savedImage)=>{
if(!err){
savedUrl.push(savedImage.url)
console.log(savedUrl)
}
})
})
res.send("Testing to upload")
} else {
console.log(err);
res.send("Error")
}
})
})
回答1:
You need to synchronize the uploads using an async callback library like async
or convert to promises. I prefer promises but the cloudinary library needs a promise wrapper.
Luckily node 8+ comes with a built-in promisify function that converts callbacks into promises. With promises your code would look like:
const { promisify } = require('util')
// Converts cloudinary callback interface into promise
const uploadAsync = promisify(cloudinary.uploader.upload.bind(cloudinary.uploader))
app.post("/newcampbook",(req,res)=>{
new formidable.IncomingForm({ multiples: true }).parse(req, async (err,fields,file)=>{
if(!err){
var pathArray = [];
file.image.forEach(e =>{
pathArray.push(e.path)
})
var savedUrl = [];
for(let e of pathArray) {
const { url } = await uploadAsync(e)
savedUrl.push(url)
}
res.send("Testing to upload")
}else{
console.log(err);
res.send("Error")
}
})
})
Now ^ that code will execute each upload synchronously one after the other. If you want to run all uploads at once (which is what your original code is doing) then it would look like:
const { promisify } = require('util')
// Converts cloudinary callback interface into promise
const uploadAsync = promisify(cloudinary.uploader.upload.bind(cloudinary.uploader))
app.post("/newcampbook",(req,res)=>{
new formidable.IncomingForm({ multiples: true }).parse(req, async (err,fields,file)=>{
if(!err){
var pathArray = [];
file.image.forEach(e =>{
pathArray.push(e.path)
})
var savedUrl = (await Promise.all(pathArray.map(uploadAsync))).map(({ url }) => url)
res.send("Testing to upload")
}else{
console.log(err);
res.send("Error")
}
})
})
If you want to use async
library, then look at the parallel
and series
functions which can do the same things directly to callbacks.
来源:https://stackoverflow.com/questions/60979043/multiple-uploads-in-cloudinary-using-node-js-and-foreach-loop