猿问

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

对于数组(产品)中的每个对象(产品),我从猫鼬数据库中获取价格。该值 (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 0

Current amount 10.29

Current amount 17.15

Current amount 18.29

Current amount 19.45

Current amount 43.2

你能帮忙吗?非常感谢!


幕布斯7119047
浏览 212回答 2
2回答

萧十郎

问题是您混合了“回调”模式和“等待”模式。要么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)

SMILET

我会使用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}));
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答