【问题标题】:what is the correct way to use async await with mariadb query in NodeJs?在 NodeJs 中使用 async await 和 mariadb 查询的正确方法是什么?
【发布时间】:2017-12-28 17:37:31
【问题描述】:

我是异步/等待的新手。

我正在尝试使用 async 和 await,但查询没有等待,它最后发生并且页面在查询之前呈现,所以我无法在呈现的页面上得到正确的答案。

这是我使用异步等待之前的代码

orderMiddleware.newOrder = function (req, res) {
    var total = 0
    var curr_total = 0
    // get items from cart
    c.query('select * from cart where user_id=:userId',
        { userId: req.user.ID }, function (err, cart) {
            if (err) {
                console.log(err)
            } else {
                cart.forEach(function (item) {
                    // Find item from DB and check their price
                    c.query('select * from products where id=:id',
                        { id: item.item_id },
                        function (err, foundItem) {
                            if (err) {
                                console.log(err)
                            } else {
                                curr_total = foundItem[0].price * item.quantity
                                console.log("currenttotal" + curr_total)
                                total += curr_total
                                console.log(total)
                            }
                        })
                })
                console.log(total)
                console.log(curr_total)
                // Calculate total price
                // Multiply all items with their quantity
                res.render('orders/new', { cart: cart, total: total })
            }
        })
}

但是这不能正常工作。 console.log(total) 发生在查询之前,因此结果为零,并且在呈现的页面中呈现为零。 如果我使用异步,也会发生同样的事情。是不是我用错了?

使用异步等待后-

orderMiddleware.newOrder = async (req, res) => {
    var total = 0
    var curr_total = 0
    // get items from cart
   var A=  c.query('select * from cart where user_id=:userId',
        { userId: req.user.ID }, async (err, cart) => {
            if (err) {
                console.log(err)
            } else {
                 cart.forEach(async (item) => {
                    // Find item from DB and check their price
                    await c.query('select * from products where id=:id',
                        { id: item.item_id },
                        async (err, foundItem) =>{
                            if (err) {
                                console.log(err)
                            } else {
                                curr_total = foundItem[0].price * item.quantity
                                console.log("currenttotal" + curr_total)
                                total += curr_total
                                console.log(total)
                            }
                        })
                })
                await console.log(total)
                // await console.log(curr_total)
                // Calculate total price
                // Multiply all items with their quantity
                await res.render('orders/new', { cart: cart, total: total })
            }
        })
}

我尝试不使用如下回调:

var A=  c.query('select * from cart where user_id=:userId',
        { userId: req.user.ID })

但是我怎样才能得到查询的输出呢? console.log(A) 显示不同的结果。

【问题讨论】:

    标签: node.js express asynchronous mariadb mariasql


    【解决方案1】:

    使用 node-mariasql,promisify 很容易使用

    const util = require('util')
    
    const asyncQuery = util.promisify(c.query);
    
    const rows = await asyncQuery.call(c, 'SELECT product FROM products WHERE id = :id', { id }, { useArray: false, metaData: false })
    

    【讨论】:

      【解决方案2】:

      你不能因为函数不返回承诺。您可以promisify 使用包含 30 部分的库(例如 es6-promisify)这些函数,也可以自己包装这些函数。

      一旦函数返回一个 Promise,你就可以等待它。

      例如,对于上述情况,解决方案可能如下:

      const execQuery = (sql, params) => new Promise((resolve, reject) => {
        query(sql, params, (error, data) => {
          if (error) {
            reject(error);
          } else {
            resolve(data);
          }
        });
      });
      
      const logCartItem = async (userId) => {
        try {
          const items = await execQuery('select * from cart where user_id=:userId', { userId });
          items.forEach(console.log);
        } catch (error) {
          console.error(error);
        }
      };
      

      【讨论】:

        【解决方案3】:

        假设您使用的是 node-mariasql 包。简短的回答是你不能使用async/await,因为包does not support Promises

        【讨论】:

        • 哦,谢谢。有没有其他方法可以做这种事情?因此,我无法获得总金额。
        猜你喜欢
        • 2014-09-20
        • 2021-07-06
        • 2018-12-16
        • 2019-04-21
        • 2021-11-15
        • 1970-01-01
        • 2018-06-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多