mongoose 如何使用异步等待与云上传API?

eyh26e7m  于 2022-11-13  发布在  Go
关注(0)|答案(1)|浏览(139)

所以下面是我的API代码,它接收两个图像文件,一个只包含一个图像,另一个包含5个图像。然后我使用一个名为cloudinary的托管网站上传它们,并收到一个结果,其中包括上传图像的URL。我试图将这些结果推到urlArray中,以便稍后我可以将它们保存到数据库中。但是,数据库的代码在其他所有事情之前执行。2还有当我在最后记录urlArray时。3它只是一个空数组。4我想知道我在这里做错了什么?

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

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

const arrayOfImages = upload.fields([
  { name: "cardImage", maxCount: 1 },
  { name: "images", maxCount: 5 },
]);
apiRouter.post(arrayOfImages, (req, res) => {
  const urlArray = [];
  let cardImage = "";
  const imagesArray = req.files["images"];
  cloudinary.uploader.upload(
    req.files["cardImage"][0].path,
    { folder: "cardImages" },
    async (err, result) => {
      if (err) console.log(err);
      cardImage = result.secure_url;
      console.log(`this is the first call ${cardImage}`);
      fs.unlinkSync(req.files["cardImage"][0].path);
    }
  );
  for (let i = 0; i < imagesArray.length; i++) {
    cloudinary.uploader.upload(
      imagesArray[i].path,
      { folder: "Images" },
      async (err, result) => {
        if (err) console.log(err);
        urlArray.push(result.secure_url);
        fs.unlinkSync(req.files["images"][i].path);
        // TODO : need to implement the data save to database
      }
    );
  }
  dataBaseConnection();
  const userItem = new Item({
    shortDescription: req.body.shortDescription,
    longDescription: req.body.longDescription,
    price: req.body.itemPrice,
    cardImage: cardImage,
    images: urlArray,
  });
  userItem.save((err) => {
    if (err) console.log(err);
    return console.log("your prodcut has been added to database.");
  });
  console.log(urlArray);
  console.log(`this is the second call ${cardImage}`);

  res.redirect("/dashboard");
});

export default apiRouter;

export const config = {
  api: {
    bodyParser: false, // Disallow body parsing, consume as stream
  },
};
w6lpcovy

w6lpcovy1#

我不熟悉coludinary API,也没有运行过这段代码,但是假设'upload'返回一个承诺(看起来是这样),你可以等待这样的结果:
注意:在wait之后,你可能需要检查result,以确保你正在立即提取属性。我对API不熟悉。但这是一般的想法。
还要注意,您可能必须将错误检查从result对象中移出。

apiRouter.post(arrayOfImages, async(req, res) => { //<< ---- Notice the async
    const urlArray = [];
    let cardImage = "";
    const imagesArray = req.files["images"];
    
    let result = await cloudinary.uploader.upload( //<<-- NOTE: await here
        req.files["cardImage"][0].path,
        { folder: "cardImages" },
        async (err, result) => {
            if (err) console.log(err);
            fs.unlinkSync(req.files["cardImage"][0].path);
        }
    )
    cardImage = result.secure_url; //<<-- pull out the value you need from result after await

    for (let i = 0; i < imagesArray.length; i++) {
        let res = await cloudinary.uploader.upload( //<<-- NOTE: await here
            imagesArray[i].path,
            { folder: "Images" },
            async (err, result) => {
                if (err) console.log(err);
                fs.unlinkSync(req.files["images"][i].path);
            }
        );
        urlArray.push(res.secure_url); //<<-- pull out the value you need from result after await
    }

    dataBaseConnection();
    const userItem = new Item({
        shortDescription: req.body.shortDescription,
        longDescription: req.body.longDescription,
        price: req.body.itemPrice,
        cardImage: cardImage,
        images: urlArray,
    });
    userItem.save((err) => {
        if (err) console.log(err);
        return console.log("your prodcut has been added to database.");
    });
    console.log(urlArray);
    console.log(`this is the second call ${cardImage}`);

    res.redirect("/dashboard");
});

这里发生了什么事?
因为upload函数是异步的,所以您的代码在第一次上载和循环之后,在'upload'实际完成之前执行。通过使用await关键字,您可以等待promise返回。

相关问题