解决Next.js CreatePurchase API异步变量更新延迟导致计算错误
问题与解决方案:药品采购API应付金额计算异常
问题描述
在使用Next.js开发药品供应商应付总额仪表盘时,createPurchase API中计算供应商新应付金额newOutstanding时,totalOrderAmount和totalPaybleGst始终为0,导致供应商应付金额更新错误。
原因分析
原代码使用forEach循环遍历药品列表,循环内部包含异步操作(查询并更新药品库存),但forEach不支持异步等待——循环会立即启动所有迭代的异步任务,不会等待每个任务完成,后续计算newOutstanding、更新供应商、创建采购单的代码会在循环内异步操作完成前执行,此时两个累加变量仍为初始值0。
解决方案
将forEach替换为for...of循环,for...of可与await配合,确保每个异步操作完成后再执行下一次迭代,保证变量累加逻辑正确执行。
修改后的createPurchase API代码:
import PurchaseOrder from '../../models/PurchaseOrder' import Supplier from '../../models/Supplier' import connectDB from '../../middleware/mongoose'; import Medicine from '../../models/Medicine'; const handler = async (req, res) => { if (req.method === 'POST') { const medicines = []; let totalOrderAmount = 0; let totalPaybleGst = 0; // 替换forEach为for...of,支持await等待异步操作完成 for (const medicine of req.body.medicines) { let medicineOne = await Medicine.findById(medicine.medicine) let newQuantity = parseInt(medicineOne.quantity) + parseInt(medicine.quantity) const filter = { _id: medicine.medicine }; const update = { quantity: newQuantity }; await Medicine.findByIdAndUpdate(filter, update); let newmedi = { name: medicine.name, company: medicine.company, medicine: medicineOne, quantity: newQuantity, pack_detail: medicine.pack_detail, category: medicine.category, batch: medicine.batch, mrp: medicine.mrp, rate: medicine.rate, gst: medicine.gst, totalAmount: medicine.totalAmount, expiryDate: medicine.expiryDate } totalOrderAmount += medicine.totalAmount; totalPaybleGst += medicine.gst * medicine.rate * medicine.quantity * 0.01; medicines.push(newmedi); } const paidAmount = req.body.paidAmount const supplierBeforeUpdate = await Supplier.findById(req.body.supplier); const newOustanding = supplierBeforeUpdate.totalOutstanding + totalPaybleGst + totalOrderAmount - paidAmount; const filter = { _id: req.body.supplier }; const update = { totalOutstanding: newOustanding }; await Supplier.findOneAndUpdate(filter, update); const supplierAffterUpdate = await Supplier.findById(req.body.supplier); const purchaseOrder = await PurchaseOrder.create({ supplier: supplierAffterUpdate, createdBy: req.body.createdBy, medicines: medicines, paybleGst: totalPaybleGst, totalAmount: totalOrderAmount, grandTotal: totalPaybleGst + totalOrderAmount, paidAmount: paidAmount }) res.status(200).json({ success: true, purchaseOrder: purchaseOrder }) } else { res.status(400).json({ error: "This method is not allowed" }) } } export default connectDB(handler);
补充说明
- 若需提升性能,可使用
Promise.all并行处理所有药品的异步操作,统一计算累加值:
// 示例:Promise.all并行处理 const medicinePromises = req.body.medicines.map(async medicine => { let medicineOne = await Medicine.findById(medicine.medicine) let newQuantity = parseInt(medicineOne.quantity) + parseInt(medicine.quantity) await Medicine.findByIdAndUpdate({ _id: medicine.medicine }, { quantity: newQuantity }); return { newmedi: { name: medicine.name, company: medicine.company, medicine: medicineOne, quantity: newQuantity, pack_detail: medicine.pack_detail, category: medicine.category, batch: medicine.batch, mrp: medicine.mrp, rate: medicine.rate, gst: medicine.gst, totalAmount: medicine.totalAmount, expiryDate: medicine.expiryDate }, totalAmount: medicine.totalAmount, gstAmount: medicine.gst * medicine.rate * medicine.quantity * 0.01 } }) const results = await Promise.all(medicinePromises); results.forEach(result => { medicines.push(result.newmedi); totalOrderAmount += result.totalAmount; totalPaybleGst += result.gstAmount; })
- 验证
totalPaybleGst的计算逻辑是否符合业务需求,确保税率百分比转换(乘以0.01)的逻辑正确。
内容的提问来源于stack exchange,提问作者Imtiyaz Nandasaniya
相关产品推荐
相关产品推荐

