सरणी (उत्पादों) में प्रत्येक ऑब्जेक्ट (उत्पाद) के लिए, मुझे एक मूंगोज़ डेटाबेस से कीमत मिल रही है। वह मान (prodDB.price) लूप से पहले 0 के रूप में इनिशियलाइज़ किए गए "अमाउंट" के बराबर होता है।

मैंने अन्य प्रश्नों में बताए गए 3 समाधानों की कोशिश की:

  • के लिए…
  • के इंतजार में
  • 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);

--- वादा करो ---

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);

कोड के किसी भी पिछले संस्करण का परिणाम हमेशा एक जैसा होता है, और अप्रत्याशित, विशेष रूप से क्रम जिसमें कंसोल होता है:

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

क्या आप मदद कर सकते हैं? आपका बहुत बहुत धन्यवाद!

1
Filipe Sim 13 अक्टूबर 2020, 18:07

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)
2
Jeremy Thille 13 अक्टूबर 2020, 15:20

मैं Promise.all का उपयोग करेगा ताकि आप समानांतर में सभी DB अनुरोध को चला सकें और सभी को श्रृंखला में चलाने के बजाय सभी के पूरा होने की प्रतीक्षा कर सकें। एक ही मुद्दा मुझे लगता है कि .exec() के साथ Promise नहीं लौट रहा है, बस findById() का उपयोग करें जो एक वादा लौटाता है, इस कोड को आज़माएं:

let amount = 0;

await Promise.all(products.map(async (product)=> {
  const prodDB = await Product.findById(product._id)
  amount += product.count * prodDB.price
}));
1
Luca Faggianelli 13 अक्टूबर 2020, 15:14