【发布时间】:2019-03-04 01:12:34
【问题描述】:
我正在尝试将带有 prod.quantity 和 prod.qtyCount 更新值的 req.session.cart 传递给 order.save() 中的 shoppingCart 字段
但问题是即使我正在使用 cartProducts[i].prod.quantity = productDbQty; 和 cartProducts[i].prod.qtyCount = getQtyArr; ,订单也会使用数量和 qtyCount 的默认值保存
奇怪的是,如果我做第二个订单,第二个订单将反映第一个订单的数量。所以基本上如果默认数量是 100 并且用户传入的新数量是 50,那么第一个订单将使用默认 100 的数量保存。第二个订单无论传入什么数量都会被保存为50,这应该是订单1的数量。
在我的模型中
// function to get an array of the quantity
module.exports.getProductCount = (qty) => {
var productCountArr = [];
for (var i=0; i <= qty; i++) {
productCountArr.push(i);
};
return productCountArr;
};
更新我添加了一堆console.log(num) 语句,这样我就可以看到发生的执行顺序。它按预期从第 1、2、3 步开始,但随后跳转到 9、10、11,这使得订单以默认数量保存。然后返回到第 4 步,在此更新订单值。因此,在数量更新发生之前,它过早地保存了订单。不过不知道怎么解决。
由于某种原因,它会跳过 Product.find() 然后保存订单,然后返回查找要更新的产品,但此时订单已经保存。
显示console.log() 语句的执行顺序的输出。
1
2
3
9
10
11
4
5
6
7
8
在我的控制器中
// save an order to the database
module.exports.saveOrder =
(req, res, next) => {
// if there is a current user logged in
if (req.user) {
// // create a new order
// let order = new Order({
// // get the shopping cart from the session
// shoppingCart: req.session.cart,
// // get the user id from passport
// userId: req.user.id,
// orderTotal: Number(req.session.cart.cartTotal),
// orderQuantity: Number(req.session.cart.cartQuantity)
// });
console.log('1');
// get the shopping cart object from the session
// var cart = req.session.cart;
var cart = new Cart(req.session.cart);
// get the products from the session cart
var products = cart.products;
console.log('2');
// loop through the products in the cart
for (var id in products) {
// quantity the user selected for the product in their session cart
prodSessionCartQty = Number(products[id].quantity);
console.log('3');
// get the product model quantity and subtract
Product.findById(id, (err, prod) => {
if (err)
console.log("Error Selecting : %s ", err);
if (!prod)
return res.render('404');
// the number of products in the product database collection
var productDbQty = Number(prod.quantity);
console.log('4');
// if their are enough products in the database
if (productDbQty >= prodSessionCartQty) {
// subtract the product session cart quantity
productDbQty = productDbQty - prodSessionCartQty;
prod.quantity = productDbQty; // store the new quantity
// update array of quantity count in product collection
var qty = prod.quantity;
var getQtyArr = ProductDb.getProductCount(qty);
prod.qtyCount = getQtyArr;
console.log('5');
// get the products in the shopping cart
var cartProducts = cart.products;
// array to hold the products of an order
var productsArray = [];
// loop through the products in the cart
for (var i in cartProducts) {
console.log('6');
// update quantities for prods in order collection
cartProducts[i].prod.quantity = productDbQty;
cartProducts[i].prod.qtyCount = getQtyArr;
// push the products into an array
productsArray.push(cartProducts[i]);
};
// store the updated prod quantities back in the cart object
cart.products = productsArray;
req.session.cart = cart;
console.log('7');
// save the new updated quantity to the database
prod.save((err, updatedProd) => {
console.log('8');
console.log(err, updatedProd);
if (err) {
res.status(500).send('save failed');
return;
}
});
}//if
}); // Product
} //for
console.log('9');
// create a new order
let order = new Order({
// get the shopping cart from the session
shoppingCart: req.session.cart,
// get the user id from passport
userId: req.user.id,
orderTotal: Number(req.session.cart.cartTotal),
orderQuantity: Number(req.session.cart.cartQuantity)
});
console.log('10');
order.save((err, resultCallback) => {
console.log('11');
// if an error occurs during checkout
if (err) {
console.log("Error Selecting : %s ", err);
req.flash('errorMessage', 'Error: checkout failed!')
res.redirect('/orders/checkout');
}
// else no error while checking out
else {
// set cart back to null so a new order can be made
req.session.cart = null;
req.flash('successMessage', 'Your order has been placed')
res.redirect('/products');
}
});
// else no logged in user
} else {
// redirect user and send login message
req.flash('errorMessage', 'Please login first!');
res.redirect('/login');
}
};
【问题讨论】:
-
在 JavaScript 中,异步代码在所有同步代码完成之前不会执行。
-
在您的情况下,这意味着传递给
Product.findById(thisCallback)或order.save()的回调将在它们周围的所有其他代码完成之前不会被调用。
标签: javascript node.js express-session