在 NodeJs 中使用 async await 和 mariadb 查询的正确方法是什么?



我是async/await的新手。

我正在尝试使用 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 })

但是,我如何获取查询的输出呢? 控制台.log(A( 显示不同的结果。

你不能,因为函数不返回承诺。您可以使用三十部分的库(例如 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);
}
};

假设您使用的是node-mariasql包。简短的回答是你不能使用async/await因为该软件包不支持承诺。

使用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 })

最新更新