Reputation: 89
I'm writing a function that calculates the total $ amount by querying the database to get the price, and then multiplying it by the quantity. It does this for every item in the array and pushes the total to an array which is then reduced to one final total number which is returned. The function is shown below:
const calculateOrderAmount = async (items: cartProduct[]): Promise<number> => {
const priceArray: number[] = [];
items.forEach(async (p: cartProduct) => {
const product = await Product.findById(p.prodId).exec();
if (product) {
const totalPrice = product.price * p.quantity;
priceArray.push(totalPrice)
} else return;
});
let amount;
if (priceArray.length === 0) amount = 0;
else amount = priceArray.reduce((a, b) => a + b);
return amount;
};
The problem that I'm having is with the asynchronicity of it. I want it to wait for the forEach
to finish, but since it's asynchronous, it keeps going and does the rest of the function first, so it end up returning 0. Is there a way to make it wait for the forEach
to finish? Or should I rewrite it in a different way
Upvotes: 1
Views: 198
Reputation: 350137
By using a forEach
callback, you create a separate series of promises, but the forEach
call itself will not await those promises.
The simple solution is to use a for
loop, which does not use a callback system:
for (let p: cartProduct of items) {
const product = await Product.findById(p.prodId).exec();
if (!product) continue;
const totalPrice = product.price * p.quantity;
priceArray.push(totalPrice);
}
Upvotes: 1
Reputation: 897
You can try the for await of
construct:
for await (variable of iterable) {
statement
}
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of
Upvotes: 3