You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用async/await优化Cloudinary上传API,解决数据库提前执行问题

问题根源

你代码里的Cloudinary图片上传是异步操作,但数据库保存、页面重定向是同步执行的。当执行到userItem.save()时,上传图片的回调函数还没跑完,cardImage和urlArray都还是初始的空值,所以数据库里存的就是空数据。

解决办法:用Promise+async/await把异步流程串起来

Cloudinary的upload方法如果不传回调,会返回Promise,咱们可以用async/await等所有上传完成后,再执行数据库操作。修改后的代码如下:

const upload = multer({
  storage: multer.diskStorage({
    destination: "./public/uploads",
    filename: (req, file, cb) => cb(null, file.originalname),
  }),
});

const apiRouter = nc({
  onNoMatch(req, res) {
    res.status(405).json({ error: `method ${req.method} not allowed` });
  },
});

const arrayOfImages = upload.fields([
  { name: "cardImage", maxCount: 1 },
  { name: "images", maxCount: 5 },
]);

// 把路由处理函数改成async函数,支持await
apiRouter.post(arrayOfImages, async (req, res) => {
  try {
    const urlArray = [];
    let cardImage = "";
    const imagesArray = req.files["images"] || []; // 兼容没传images的情况

    // 等待单张cardImage上传完成
    const cardUploadResult = await cloudinary.uploader.upload(
      req.files["cardImage"][0].path,
      { folder: "cardImages" }
    );
    cardImage = cardUploadResult.secure_url;
    fs.unlinkSync(req.files["cardImage"][0].path);

    // 批量上传images,用Promise.all等所有上传完成
    const imageUploadPromises = imagesArray.map(async (imageFile) => {
      const uploadResult = await cloudinary.uploader.upload(
        imageFile.path,
        { folder: "Images" }
      );
      fs.unlinkSync(imageFile.path);
      return uploadResult.secure_url;
    });
    // 把所有上传后的URL存入urlArray
    urlArray.push(...await Promise.all(imageUploadPromises));

    // 现在所有图片都上传完了,再存数据库
    dataBaseConnection();
    const userItem = new Item({
      shortDescription: req.body.shortDescription,
      longDescription: req.body.longDescription,
      price: req.body.itemPrice,
      cardImage: cardImage,
      images: urlArray,
    });
    await userItem.save(); // 等待数据库保存完成
    console.log("your product has been added to database.");

    res.redirect("/dashboard");
  } catch (err) {
    // 统一处理所有错误,避免程序挂掉
    console.error(err);
    res.status(500).json({ error: "Failed to upload images and save item" });
  }
});

export default apiRouter;

export const config = {
  api: {
    bodyParser: false, // Disallow body parsing, consume as stream
  },
};
关键修改点
  • 把路由处理函数改成async,这样内部可以用await等待异步操作
  • Cloudinary上传不再传回调,改用await等单个上传完成
  • 多张图片上传用map生成Promise数组,再用Promise.all一次性等所有上传完成,拿到所有URL
  • 数据库保存也用await,确保数据存成功再重定向
  • 加了try/catch捕获所有错误,避免意外崩溃

这样就能保证所有图片上传完成、URL都存进数组后,再执行数据库操作,解决urlArray为空的问题。

内容的提问来源于stack exchange,提问作者Kamran

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 03:35:22