为了账号安全,请及时绑定邮箱和手机立即绑定

for...of, for await...of 和 Promise.all

for...of, for await...of 和 Promise.all

幕布斯7119047 2023-05-11 15:53:17
对于数组(产品)中的每个对象(产品),我从猫鼬数据库中获取价格。该值 (prodDB.price) 与在循环之前初始化为 0 的“金额”变量相加。我尝试了其他问题中解释的 3 种解决方案,其中:对于等待承诺.all--- 对于 --- let amount = 0;      for (const product of products) {     await Product.findById(product._id).exec((err, prodDB)=> {         amount += product.count * prodDB.price;         console.log("Current amount", amount);     }); }; console.log("Amount total", amount);---等待--- let amount = 0;      for await (const product of products) {     Product.findById(product._id).exec((err, prodDB)=> {         amount += product.count * prodDB.price;         console.log("Current amount", amount);     }); }; console.log("Amount total", amount);--- Promise.all ---let amount = 0;await Promise.all(products.map(async (product)=> {    await Product.findById(product._id).exec((err, prodDB)=> {    amount += product.count * prodDB.price;    console.log("Current amount", amount);    });})); console.log("Amount total", amount);任何以前版本的代码的结果总是相同的,而且出乎意料,尤其是 console.log 发生的顺序:Amount total 0Current amount 10.29Current amount 17.15Current amount 18.29Current amount 19.45Current amount 43.2你能帮忙吗?非常感谢!
查看完整描述

2 回答

?
萧十郎

TA贡献1815条经验 获得超13个赞

问题是您混合了“回调”模式和“等待”模式。要么await操作,要么给它一个回调,否则它会变得混乱。


for (const product of products) {

    let prodDB = await Product.findById(product._id).lean().exec(); // add lean() to get only JSON data, lighter and faster

    amount += product.count * prodDB.price;

    console.log("Current amount", amount);

};

然而,这是非常昂贵的,因为如果您有 10 个产品,您将调用数据库 10 次。最好只调用一次并一次获取所有 _id。


let allIds = products.map(p => p._id),

    prodDBs = await Product.find({

        _id: {

            $in: allIds

        }

    })

    .lean()

    .exec()


const amount = prodDBs.reduce((a,b) => a.price + b.price, 0)


查看完整回答
反对 回复 2023-05-11
?
SMILET

TA贡献1796条经验 获得超4个赞

我会使用Promise.all这样你就可以并行运行所有的数据库请求并等待它们全部完成,而不是依次运行它们。我认为唯一的问题是.exec()不返回 a Promise,只使用findById()它返回一个 Promise,试试这个代码:


let amount = 0;


await Promise.all(products.map(async (product)=> {

  const prodDB = await Product.findById(product._id)

  amount += product.count * prodDB.price

}));


查看完整回答
反对 回复 2023-05-11
  • 2 回答
  • 0 关注
  • 192 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信