JavaScript中forEach内return无法终止外层函数执行的原因咨询
问题解答:forEach中的return无法终止外层点击事件函数
问题原因
你写的return是在forEach的回调函数内部,这个return只能终止当前这一次的回调执行,跳出当前的循环迭代,根本不会影响外层的点击事件处理函数。而且forEach本身就不支持通过return终止整个循环,哪怕你在回调里return,forEach还是会遍历完所有元素,外层函数自然会继续执行后面的代码。
解决方案
要实现“找到匹配商品后,终止外层点击事件函数”的需求,可以换用其他遍历方式,同时设置标记来控制外层代码的执行:
方案1:使用for循环 + 标记变量
把forEach换成普通的for循环,找到匹配项时设置标记并终止循环,之后在外层判断标记,决定是否继续执行后续添加新商品的代码:
addtoCart.addEventListener('click', (e) => { quantity_on_cart = parseInt(cartItems.innerText); let quantity = parseInt(i.innerHTML); let productExists = false; // 标记是否找到已存在的商品 if (quantity === 0) { cartItems.innerText = quantity_on_cart + quantity; } else { cartItems.innerText = quantity_on_cart + quantity; let div = document.createElement("div"); let product_nameIn_cart = document.getElementsByClassName("product_nameIn_cart"); // 将HTMLCollection转为数组,用for...of循环遍历 const productArray = [...product_nameIn_cart]; for (let x of productArray) { if (product_name === x.innerHTML) { // 更新已存在商品的数量和总价 const targetItem = x.parentNode.parentNode; const currentQuan = parseInt(targetItem.querySelector(".quan").value); targetItem.querySelector(".quan").value = currentQuan + parseInt(i.innerText); targetItem.querySelector(".total").innerHTML = parseInt(targetItem.querySelector(".quan").value) * parseInt(product_price); calTotal(); productExists = true; break; // 终止循环,不再遍历后续元素 } } // 如果商品已存在,直接终止外层点击事件函数 if (productExists) return; // 以下是添加新商品的代码,只有商品不存在时才会执行 console.log("Hello World"); div.classList.add("d-flex", "justify-content-around", "my-3", "displayDel"); div.innerHTML = ` <div> <div class="product_nameIn_cart">${product_name}</div> <div class="delcontainer"> <button class=" btn btn-sm btn-danger" onclick="cancel(this)">Cancel</button> </div> </div> <div>${parseInt(product_price)}</div> <div> <input class="quan" type="number" min="0" value="${parseInt(i.innerText)}" onclick="quan(this)"/> </div> <div class="total">${parseInt(product_price)*parseInt(i.innerText)}</div> `; order_submit.append(div); calTotal(); } })
方案2:使用Array.some()方法
some()方法会遍历数组,当回调函数返回true时,会立即停止遍历并返回true。我们可以利用这个特性,判断是否找到匹配的商品,再决定是否终止外层函数:
addtoCart.addEventListener('click', (e) => { quantity_on_cart = parseInt(cartItems.innerText); let quantity = parseInt(i.innerHTML); if (quantity === 0) { cartItems.innerText = quantity_on_cart + quantity; } else { cartItems.innerText = quantity_on_cart + quantity; let div = document.createElement("div"); let product_nameIn_cart = document.getElementsByClassName("product_nameIn_cart"); // some()返回true表示找到匹配的商品,且会立即停止遍历 const productExists = [...product_nameIn_cart].some((x) => { if (product_name === x.innerHTML) { // 更新已存在商品的数量和总价 const targetItem = x.parentNode.parentNode; const currentQuan = parseInt(targetItem.querySelector(".quan").value); targetItem.querySelector(".quan").value = currentQuan + parseInt(i.innerText); targetItem.querySelector(".total").innerHTML = parseInt(targetItem.querySelector(".quan").value) * parseInt(product_price); calTotal(); return true; // 让some()停止遍历,并返回true } return false; }); // 如果商品已存在,直接终止外层点击事件函数 if (productExists) return; // 以下是添加新商品的代码,只有商品不存在时才会执行 console.log("Hello World"); div.classList.add("d-flex", "justify-content-around", "my-3", "displayDel"); div.innerHTML = ` <div> <div class="product_nameIn_cart">${product_name}</div> <div class="delcontainer"> <button class=" btn btn-sm btn-danger" onclick="cancel(this)">Cancel</button> </div> </div> <div>${parseInt(product_price)}</div> <div> <input class="quan" type="number" min="0" value="${parseInt(i.innerText)}" onclick="quan(this)"/> </div> <div class="total">${parseInt(product_price)*parseInt(i.innerText)}</div> `; order_submit.append(div); calTotal(); } })
内容的提问来源于stack exchange,提问作者Lycan
相关产品推荐
相关产品推荐

