【问题标题】:Mongoose query inside a forEach loop can't return or set value for sum variableforEach 循环内的 Mongoose 查询无法返回或设置 sum 变量的值
【发布时间】:2021-11-04 13:14:25
【问题描述】:

我正在尝试使用 findById 计算从数据库查询的每个产品价格的总和。 id 来自我使用 forEach 循环迭代的对象数组。

module.exports.checkoutOrder = (reqBody, buyerId, isAdmin)=>{

    let sum =0;
    reqBody.items.forEach(item=>{

         Product.findById(item.productId,(error, result)=>{

            //console.log(result.price);
            sum += result.price;

        })
    }) console.log(sum);

问题是,我似乎无法在 findById 块中获取或设置任何变量。即使我将 return 放在 sum 变量上,它始终是相同的结果 0。我确信当我 console.log result.price 时我的查询正在返回一个数据。

我知道还有其他方法可以对数据求和,我只是想先知道为什么它不能这样工作?

【问题讨论】:

  • @NiceBooks,我怎样才能输出总和?我只是把它放在循环之外
  • 请参考我的回答。

标签: javascript node.js mongodb mongoose


【解决方案1】:

findById (err,result)=>{} 的第二个参数是一个回调,它本质上不会立即运行。 console.log(sum) 在所有回调之前运行,因此打印 0。

您需要等到所有回调都运行完毕。一个粗略的解决方案是将console.log(sum) 包裹在setTimeout 中,并有合理的延迟。

更好的解决方案是使用 exec 方法创建 Promise 对象 Promise.all 方法等待所有承诺完成。

let promiseList = await reqBody.items.map(async (item,i)=> 
  Product.findById(item.productId).exec() 
);

Promise.all(promiseList).then((productList)=> {
  let sum = productList.reduce((acc,product)=> acc + product.price, 0);
  console.log(sum);
});

【讨论】:

  • 你好。我认为这段代码的格式已经正确并尝试过,但我得到一个错误“等待仅在异步函数中有效”
  • 我仍然收到相同的错误“等待仅在异步函数中有效”。我完全删除了 forEach 并用您的代码替换了它。错误指向reqBody之前的await
  • 我用虚拟数字而不是猫鼬查询检查了代码,它可以工作。你有没有在 map 回调之前添加 async 关键字,在 findById 之后添加 exec() 方法调用?
  • 最好将新代码作为编辑添加到您的原始问题中,以便其他人可以看到。我认为您必须在 (reqBody,buyerId,isAdmin)=> 之前添加异步,因为您在内部使用 await。
  • 哇。在我将异步放在(reqBody,buyerId,isAdmin)=> 之前,它现在可以工作了。终于解脱了。我要彻底研究你的代码。我不想盲目地编码。谢谢
【解决方案2】:

您可以尝试从数组中获取所有具有 id 的文档:

const arrOfIds = reqBody.items.map(item => item.id)
Product.find({ '_id': { $in: arrOfIds }}).toArray(function(err, data)...

然后你就可以计算sum了。

【讨论】:

  • 你的意思是我可以在没有 forEach 循环的情况下做到这一点?
  • 是的,您可以从 reqBody.items 准备只有 id 的数组,然后获取具有该 id 的产品
  • 你能帮我如何格式化你的代码吗?抱歉,这对我来说似乎是新的。我收到错误 Product.find 不是函数
  • 好的,我现在可以 console.log arrOfIds。关于to.Array函数的结束代码,如何输出结果数据?
  • 您好,希望您还可以阅读本文。请问那个代码中的“$in”是做什么的?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多