JavaScript异步函数中for循环后代码未执行问题求助
问题定位与修复方案
核心问题:数组越界导致代码中断
循环后代码不执行的根本原因是第一个for循环的终止条件错误:
for (let i = 0; itemCount >= i; i++) {
当i等于itemCount时,orderItems[i]会是undefined(数组索引范围是0到itemCount-1),此时访问orderItems[i].itemId会抛出TypeError,异步函数因未捕获的异常终止,后续代码自然不会执行。
修复循环条件
把循环条件改为:
for (let i = 0; i < itemCount; i++) {
其他潜在问题(会导致后续代码执行异常)
除了核心问题,代码里还有几个必须修复的问题:
discount初始值为null,后续访问属性会报错discount一开始被赋值为null,后面直接访问discount.type、discount.itemNum等属性会抛出TypeError。需要确保调用函数时discount已被正确赋值,或者在访问前加存在性判断:if (discount?.type === "Item" && discount?.itemNum == j.sku) {第二个
for循环中错误使用外部变量i
第二个for...of循环里的orderItems[i].lineTax,这里的i是第一个循环的变量,此时i已经等于itemCount,会再次导致数组越界。应该直接使用当前循环的j对象:j.lineTax = parseFloat((itemPrice * taxRate).toFixed(2));return orderItems, orderTotals写法错误
这种逗号表达式只会返回最后一个值orderTotals,如果需要返回两个值,应该返回对象或数组:return { orderItems, orderTotals };discountAmt变量作用域问题
在订单折扣逻辑中定义的discountAmt,后续赋值给orderTotals.discountAmount时会因作用域问题找不到变量,需要把discountAmt提升到函数顶部。
修正后的完整代码
const calculateTotal = async (order, next) => { let itemPrice; let total = 0; let discount = null; // 确保调用该函数时discount已被正确赋值 let orderItems = []; let discountAmt = 0; // 提升作用域,避免后续访问不到 let orderTotals = { subTotal: null, discountAmount: null, shippingAmount: null, taxAmount: null, total: null, }; const taxRate = 0.0825; const taxFright = "Y"; order.items.map((i) => { orderItems.push({ itemId: i.itemId, sku: i.sku, quantity: i.quantity, price: i.price, lineTax: 0, fulfilled: false, }); }); const itemCount = orderItems.length; console.log(itemCount); //Check SKU for any price changes prior to order processing for (let i = 0; i < itemCount; i++) { // 修复循环条件 let itemId = orderItems[i].itemId; let checkProduct = await Products.findById(itemId); console.log(itemId); if (checkProduct) { let productPrice = checkProduct.price; let itemsPrice = orderItems[i].price; let isInStock = checkProduct.quantity >= 5; if (isInStock) { console.log("Item in Stock"); if (productPrice !== itemsPrice) { orderItems[i].price = productPrice; } } else { console.log("Item " + (i + 1) + " - Remove Items from Cart & Notify User"); } } else { console.log("Can't find product"); } } console.log("Discount Section"); console.log(orderItems); //Apply Discount to Order/Items for (let j of orderItems) { discountAmt = 0; console.log(j); // 增加discount存在性判断 if (discount?.type === "Item" && discount?.itemNum == j.sku) { if (discount.method === "Percent") { discountAmt = j.price * (discount.amount / 100); itemPrice = (j.price.toFixed(2) - discountAmt.toFixed(2)) * j.quantity; total += itemPrice; j.lineTax = parseFloat((itemPrice * taxRate).toFixed(2)); // 改为j } else if (discount.method === "Fixed") { discountAmt = discount.amount.toFixed(2); itemPrice = j.price.toFixed(2) * j.quantity - discountAmt; total += itemPrice; j.lineTax = parseFloat((itemPrice * taxRate).toFixed(2)); // 改为j } else { return next(new ErrorResponse("Unable to Calculate the Discount for your order. Please send an email to IT", 401)); } } else { console.log("No Discount"); itemPrice = j.price.toFixed(2) * j.quantity; total += itemPrice; j.lineTax = parseFloat((itemPrice * taxRate).toFixed(2)); } } if (discount?.type === "Order") { // 增加存在性判断 if (discount.method === "Fixed") { discountAmt = discount.amount; } else if (discount.method === "Percent") { discountAmt = total * (discount.amount / 100); } else { return next(new ErrorResponse("Discount Method isn't set corretly. Please submit an IT Ticket", 401)); } total -= discountAmt.toFixed(2); } console.log(total); //Calculate Tax for Order - Missing Discount for Entire Order if (total > 0) { orderTotals.subTotal = total; orderTotals.discountAmount = discountAmt; if (taxFright == "Y") { orderTotals.shippingAmount = 5.0; orderTotals.taxAmount = parseFloat(((total + orderTotals.shippingAmount) * taxRate).toFixed(2)); } else { orderTotals.shippingAmount = 0; orderTotals.taxAmount = parseFloat((total * taxRate).toFixed(2)); } orderTotals.total = parseFloat((orderTotals.subTotal + orderTotals.shippingAmount + orderTotals.taxAmount).toFixed(2)); } return { orderItems, orderTotals }; // 修正return写法 };
内容的提问来源于stack exchange,提问作者Andrew Vargas
相关产品推荐
相关产品推荐

