Oracle Apex中Break语句无法跳出嵌套循环问题排查
问题:带标签的break未正确阻止else块执行
我尝试在满足特定条件时跳出外层循环,给每个循环添加了标签并使用break指定要跳出的循环,但未生效。即使break语句执行了,else块内的console.log(1)仍会向控制台打印1,我的JavaScript代码哪里出错了?
表格HTML代码
<table class="t-Report-report ui-sortable" id="seq_report"> <thead> <tr class="ui-sortable-handle"> <th class="t-Report-colHead" align="left" id="PK_DISPLAY"> </th> <th class="t-Report-colHead" align="center" id="POS_NBR">Position</th> <th class="t-Report-colHead" align="center" id="DISP_VAL">Description</th> <th class="t-Report-colHead" align="center" id="SEQ_NBR">Seq</th> <th class="t-Report-colHead" align="center" id="PERM"></th> </tr> </thead> <tbody> <tr data-id="19691" class="ui-sortable-handle"> <td class="t-Report-cell" headers="PK_DISPLAY"><a href="#" data-id="19691"></a></td> <td class="t-Report-cell" headers="POS_NBR">05M</td> <td class="t-Report-cell" headers="DISP_VAL">t05</td> <td class="t-Report-cell" headers="SEQ_NBR">1</td> <td class="t-Report-cell" headers="PERM">Perm</td> </tr> <tr data-id="19692" class="ui-sortable-handle"> <td class="t-Report-cell" headers="PK_DISPLAY"><a href="#" data-id="19692"></a></td> <td class="t-Report-cell" headers="POS_NBR">06M</td> <td class="t-Report-cell" headers="DISP_VAL">t06</td> <td class="t-Report-cell" headers="SEQ_NBR">2</td> <td class="t-Report-cell" headers="PERM">Perm</td> </tr> <tr data-id="19690" class="ui-sortable-handle"> <td class="t-Report-cell" headers="PK_DISPLAY"><a href="#" data-id="19690"></a></td> <td class="t-Report-cell" headers="POS_NBR">04M</td> <td class="t-Report-cell" headers="DISP_VAL">t04</td> <td class="t-Report-cell" headers="SEQ_NBR">3</td> <td class="t-Report-cell" headers="PERM">Perm</td> </tr> <tr data-id="19687" class="ui-sortable-handle"> <td class="t-Report-cell" headers="PK_DISPLAY"><a href="#" data-id="19687"></a></td> <td class="t-Report-cell" headers="POS_NBR">04M</td> <td class="t-Report-cell" headers="DISP_VAL">t04</td> <td class="t-Report-cell" headers="SEQ_NBR">4</td> <td class="t-Report-cell" headers="PERM">Temp</td> </tr> </tbody> </table>
JavaScript代码
function makeSortable(pRegionID) { var $r = $("#report_" + pRegionID); var r = $r[0];// add ID to TR element so we know the correct position var $perm; var $obj; $r.find("[headers='PK_DISPLAY'] a").each(function () { //console.log($(this)); $(this).parent().parent().attr('data-id', $(this).data("id")); // $(this).closest('tr').attr('data-id',$(this).data("id")); });// finally make it sortable $r.find("table.t-Report-report").sortable({ items: 'tr' , containment: r , helper: fixHelper , update: function (event, ui) { var found = 0; $obj = $r.find("[headers='POS_NBR']"); $perm = $obj.next().next().next(); loop1:for (var i = 0; i < $obj.length - 1; i++) { loop2:for (var j = 0; j < $obj.length - 1 - i; j++) { if ($obj[i].innerHTML == $obj[i + 1 + j].innerHTML && $perm[i].innerHTML == 'Temp') { apex.message.alert("Go out"); apex.event.trigger($r, 'apexrefresh'); break loop1; }else{ console.log(1); updateDisplaySeq(r); } } } } }); }
问题分析与修复
核心问题
你的break逻辑本身是有效的,但else块会在每一次内层循环不满足if条件时执行。也就是说,在触发break跳出外层循环之前,内层循环已经经历了多次不满足条件的迭代,这些迭代都会执行console.log(1),所以你会看到控制台打印1。
另外,循环结构存在冗余:
- 内层循环的
j从0开始,导致重复比较同一组元素(比如i=0时会比较索引0和1、0和2;i=1时又会比较1和2) - else块里的
updateDisplaySeq(r)会被重复调用,造成不必要的性能损耗
修复后的代码
function makeSortable(pRegionID) { var $r = $("#report_" + pRegionID); var r = $r[0]; var $perm; var $obj; $r.find("[headers='PK_DISPLAY'] a").each(function () { $(this).parent().parent().attr('data-id', $(this).data("id")); }); $r.find("table.t-Report-report").sortable({ items: 'tr' , containment: r , helper: fixHelper , update: function (event, ui) { var found = false; // 用布尔值标记是否触发条件 $obj = $r.find("[headers='POS_NBR']"); $perm = $obj.next().next().next(); loop1:for (var i = 0; i < $obj.length - 1; i++) { // 调整j的起始值,避免重复比较 for (var j = i + 1; j < $obj.length; j++) { if ($obj[i].innerHTML == $obj[j].innerHTML && $perm[i].innerHTML == 'Temp') { apex.message.alert("Go out"); apex.event.trigger($r, 'apexrefresh'); found = true; break loop1; } } } // 只有完全没触发条件时,才执行后续逻辑 if (!found) { console.log(1); updateDisplaySeq(r); } } }); }
关键改进点
- 把原else块的逻辑移到循环结束后,通过
found标记判断是否执行,避免循环过程中重复打印和调用方法 - 调整内层循环的
j起始值为i+1,消除重复比较,提升循环效率 - 用布尔变量
found替代数字标记,语义更清晰
内容的提问来源于stack exchange,提问作者qka
相关产品推荐
相关产品推荐

