使用 Node Js 和 ForEach 循环在 cloudinary 中进行多次上传
Multiple Uploads in cloudinary using Node Js and ForEach loop
我有一个输入标签可以上传多张图片,并使用 cloudinary 和 formidable 包将它们上传到 cloudinary。
理想情况下,我想提取 URL 并将其保存在我的数据库中,我拥有所有其他信息。
但未能检索到下面显示在数组中的 URL。
以它为目标创建一个对象,用 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")
}
})
})
您需要使用 async
之类的异步回调库来同步上传或转换为 promises。我更喜欢承诺,但 cloudinary 库需要一个承诺包装器。
幸运的是,node 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
函数,它们可以直接对回调执行相同的操作。
我有一个输入标签可以上传多张图片,并使用 cloudinary 和 formidable 包将它们上传到 cloudinary。
理想情况下,我想提取 URL 并将其保存在我的数据库中,我拥有所有其他信息。
但未能检索到下面显示在数组中的 URL。
以它为目标创建一个对象,用 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")
}
})
})
您需要使用 async
之类的异步回调库来同步上传或转换为 promises。我更喜欢承诺,但 cloudinary 库需要一个承诺包装器。
幸运的是,node 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
函数,它们可以直接对回调执行相同的操作。