【问题标题】:How to stop execution until function finishes如何停止执行直到函数完成
【发布时间】:2021-12-20 20:43:27
【问题描述】:

我正在使用 NodeJS 和 MongoDB (Mongoose) 开发电子商务网络应用程序。
我有一条可以在购物车中显示产品的获取路线,但我正在苦苦挣扎,因为我需要完成一个功能,然后才能继续执行其余代码。
该函数将项目推送到一个数组,然后我尝试渲染一个传递该数组的视图,但该数组消失为空。

这是我的代码。

router.get('/cart', function (req, res) {
  User.findOne({ username: req.user.username }, function (err, doc) {
    // This is the array that needs to be passed
    const prodAndQty = [];
    const prodEntries = Object.entries(doc.shoppingCart);
    // This is the function that I need to complete before continuing
    prodEntries.forEach(function (entry) {
      Product.findOne({ id: entry[0] }, function (err, doc) {
        prodAndQty.push([doc, entry[1]]);
      });
    });
    if (err) { console.log(err); }
    else {
      // If I log here, the array is empty.
      console.log(prodAndQty);
      if (doc) {
        res.render('cart', { doc: doc, qty: prodEntries.length, products: prodAndQty });
      } else {
        res.render('cart', { doc: null, qty: 0, products: null });
      }
    }
  });
});

如果我在渲染之前记录数组,则数组为空。
此外,在终端中,即使在 Mongoose 查询执行之前,数组也会被记录。

Terminal log

如果我在正在推送的函数中记录数组,则数组已正确填充,但为时已晚,无法使用。

任何帮助将不胜感激。

【问题讨论】:

    标签: javascript node.js arrays mongodb mongoose


    【解决方案1】:

    试试这样的 -

    router.get('/cart', async function (req, res) {
        try {
            const doc = await User.findOne({ username: req.user.username });
    
            if(!doc) {
                res.render('cart', { doc: null, qty: 0, products: null });
            }
    
            const prodEntries   = Object.entries(doc.shoppingCart);
    
            // Instead of one by one searching, I used `in` operator (you can do one by one too, if you want)
            const entires       = prodEntries.map((prod) => {
                return prod[0];
            })
    
            const prodAndQty    = await Product.find({ id : { $in : entires }});
            // TODO - Modify this prodAndQty array as you want
    
            res.render('cart', { doc: doc, qty: prodEntries.length, products: prodAndQty });
    
        } catch(err) {
            throw new Error(err);
        }
    }
    

    在您的方法中,发生的情况是,您使用的是回调函数,它不等待代码在 forEach 中执行,它只是继续并返回响应。

    Async-await 是一个语法糖,它可以让你以某种方式编写代码,所以它似乎是以串行方式执行的。另一种方法是使用promises

    【讨论】:

    • 我在你发布这个答案之前修复了它,但我的修复看起来几乎完全一样!谢谢你的帮助。
    【解决方案2】:

    您的代码需要称为promise-based behavior 的东西。请参考:

    1. async functions
    2. promise

    【讨论】:

    • 我尝试添加一些 async/await,但我是这个概念的新手,不知道如何将其正确应用到我的项目中,您能给我一些建议吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-24
    • 1970-01-01
    相关资源
    最近更新 更多