【问题标题】:Using async/await with for loop and mongodb将 async/await 与 for 循环和 mongodb 一起使用
【发布时间】:2021-02-27 14:45:58
【问题描述】:

我想在客户完成订单后向他们发送一封订单确认电子邮件(带有 nodemailer)。
在这封确认邮件中,我想插入一些购买产品的数据。

我使用了许多 async/await 组合,但没有一个成功。
我现在得到的代码:

async function getProductData(products) {
  let productsArray = products;
  try {
    let productsHtml = "";
    for await (const product of productsArray) { // loop through the products
      db.collection("collectionname").findOne(query, (err, data) => { // get data for every product
        if (err) console.log(err)
         else {
           let productHtml = `<p>productname: ${data.productname}</p>
                             <img src="${data.imageSrc}">`;
           productsHtml += productHtml; // add the product html string to productsHtml
         }
      })
    }
  } catch (error) {
    console.log(error);
  }
  return productsHtml; //return the productsHtml string. But it returns "", because it doesn't await the mongodb function
}

async function sendConfirmationMail() {
  let productsHtml = await getProductData(products); //"products" is an array

  //nodemailer code
  let transporter = nodemailer.createTransport({
    // configuration
  });

  let email = await transporter.sendMail({
    //email information
   html: `<p>Thank you for your order!</p>
          ${productsHtml}`;, // insert the html string for all products into the mail
  });
}

问题是getProductData() 中的 return 语句在 for 循环完成之前触发。然后返回 undefined。

有人对我如何在这里以正确的方式实现 async/await 有提示吗?

【问题讨论】:

  • 仅仅是因为您没有等待数据库调用。您正在向它传递一个回调,因此它不会返回 Promise 并异步解析。只需await 并删除回调。
  • @JeremyThille 我已将 await 添加到 db 调用中(仍然返回未定义)。但是你的意思是删除什么回调? getProductData() 回调?
  • .findOne(query, (err, data) =&gt; { 这有一个回调。您将一个函数作为第二个参数传递给它,它将(err,data) 作为它自己的参数。您需要删除此回调并将async/await 语法与try/catch 一起使用。类似const data = await db.collection("collectionname").findOne(query);
  • 另一方面,您不需要for await (const product of productsArray)。您正在迭代一个静态值数组,而不是一个 Promises 数组。删除此await
  • @JeremyThille 谢谢!现在可以了。感谢帮助

标签: javascript node.js mongodb async-await


【解决方案1】:

您没有在等待数据库调用。您正在向它传递一个回调,因此它不会返回 Promise :

.findOne(query, (err, data) => {

这有一个回调。您将一个函数作为第二个参数传递给它,它将 (err,data) 作为它自己的参数。您需要删除此回调并将async/await 语法与try/catch 一起使用。类似的东西

const data = await db.collection("collectionname").findOne(query);

另一方面,您不需要for await (const product of productsArray)。您正在迭代一个静态值数组,而不是一个 Promises 数组。删除这个等待。

【讨论】:

    猜你喜欢
    • 2020-09-24
    • 2022-06-23
    • 2019-03-12
    • 1970-01-01
    • 2018-09-03
    • 1970-01-01
    • 1970-01-01
    • 2018-11-21
    相关资源
    最近更新 更多