我有一个输入标签,可以使用cloudinary和强大的软件包上传多张图像并将其上传到cloudinary。
理想情况下,我想提取URL并将其保存在我拥有所有其余信息的数据库中。
但是未能检索下面显示在数组中的URL。
以它为目标,以创建一个要使用URL保存在数据库中的对象。
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")
}
})
})
您需要使用异步回调库(例如async
)同步上载,或转换为Promise。我更喜欢promise,但是cloudinary库需要一个promise包装器。幸运的是,节点8+带有内置的promisify函数,可将回调转换为promise。有了诺言,您的代码将如下所示:
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")
}
})
})
现在^该代码将一个接一个地同步执行每个上载。如果您想一次运行所有上载(这就是您的原始代码所做的事情),那么它将看起来像:
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")
}
})
})
如果要使用async
库,请查看可以直接对回调执行相同操作的parallel
和series
函数。