for ... of,await ... of和Promise.all中的Javascript异步/等待执行顺序问题 [英] Javascript async/await execution order problem in for...of, for await...of and Promise.all

查看:209
本文介绍了for ... of,await ... of和Promise.all中的Javascript异步/等待执行顺序问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于数组(产品)中的每个对象(产品),我从猫鼬数据库中获取价格.该值(prodDB.price)被求和为金额".变量在循环之前初始化为0.

For each object (product) in an array (products), I'm getting the price from a mongoose database. That value (prodDB.price) is summed to the "amount" variable initialized as 0 before the loop.

我尝试了3个在其他问题中解释过的解决方案,

I tried 3 solutions explained in other questions, with:

  • 等待中
  • Promise.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 ---

--- 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发生的顺序:

The result of any of the previous versions of the code is always the same, and unexpected, particularly the order in which console.log happens:

Amount total 0
Current amount 10.29
Current amount 17.15
Current amount 18.29
Current amount 19.45
Current amount 43.2

可以帮忙吗?非常感谢你!

Can you please help? Thank you very much!

推荐答案

问题是您正在混合回调"模式和等待"模式模式. await 操作,或者给它回调,否则会变得混乱.

The problem is that you are mixing "callback" mode and "await" mode. Either await the operation, or give it a callback, otherwise it gets messy.

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.

However, this is very expensive, because if you have 10 products, you call your database 10 times. Better call it only once and fetch all _id in one go.

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)

这篇关于for ... of,await ... of和Promise.all中的Javascript异步/等待执行顺序问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆