【问题标题】:node javascript function order of execution [duplicate]节点javascript函数执行顺序[重复]
【发布时间】:2019-03-04 01:12:34
【问题描述】:

我正在尝试将带有 prod.quantityprod.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


【解决方案1】:

const getQtyArr = ProductDb.getProductCount(qty); 这一行可能是一个承诺。如果是这种情况,则直到循环运行后才会返回值。这可以解释为什么下一个订单会看到前一个值。使用 async/await 并等待解决此问题可能会解决您的问题。

【讨论】:

  • 我是节点新手,我刚刚阅读了 Promise,我没有使用。我将 getProductCount 函数的代码添加到问题中。谢谢。
猜你喜欢
  • 2018-10-09
  • 2013-04-19
  • 1970-01-01
  • 1970-01-01
  • 2017-04-21
  • 1970-01-01
  • 2019-08-09
  • 1970-01-01
  • 2020-09-07
相关资源
最近更新 更多