使用Stripe搭建支付系统时,forEach异步更新fullPrice失效求助
问题原因
你遇到的问题核心是forEach不会等待内部的异步操作完成。每个async回调都是独立的异步任务,forEach会快速遍历完所有元素,直接执行后续的console.log(fullPrice)——此时所有数据库查询还没结束,fullPrice自然还是初始值0。
另外你的代码还有两个细节问题:
User.findById(userId)是异步操作,必须加await,否则user会是Promise对象而非实际用户数据calculatedPrice是同步计算,不需要加await
解决方法
方法一:用for...of循环(顺序执行查询)
for...of可以配合await,等待每个异步操作完成后再进入下一次循环,确保fullPrice在所有计算完成后再输出:
const { userId, products } = req.body; // 等待用户查询完成 const user = await User.findById(userId); let fullPrice = 0; try { for (const product of products) { const foundProduct = await Product.findOne({ _id: product.productId }); // 同步计算单种商品总价 const calculatedPrice = foundProduct.price * product.quantity; fullPrice += calculatedPrice; console.log(fullPrice.toFixed(2)); } // 所有计算完成后输出最终总价 console.log(fullPrice); } catch (error) { console.log(error); }
方法二:用Promise.all(并行执行查询,效率更高)
如果不需要按顺序查询商品,用Promise.all可以同时发起所有数据库请求,等全部完成后再统一计算总价,这种方式比顺序执行更快:
const { userId, products } = req.body; const user = await User.findById(userId); let fullPrice = 0; try { // 生成所有商品价格计算的Promise数组 const pricePromises = products.map(async product => { const foundProduct = await Product.findOne({ _id: product.productId }); return foundProduct.price * product.quantity; }); // 等待所有Promise完成,得到每种商品的总价数组 const productTotalPrices = await Promise.all(pricePromises); // 累加所有商品总价 fullPrice = productTotalPrices.reduce((total, price) => total + price, 0); console.log(fullPrice); } catch (error) { console.log(error); }
内容的提问来源于stack exchange,提问作者MK BOZ
相关产品推荐
相关产品推荐

