for循环配合setTimeout时break语句无法终止定时任务的问题
解决setTimeout配合for循环无法终止定时任务的问题
你的代码里,for循环是同步执行的,会一次性把j从0到5的task(j)全部调用完毕——每个task都会立刻创建对应的setTimeout定时器。break语句只是终止了后续的循环迭代,但已经创建的定时器不会被取消,所以这些定时任务还是会按设置的时间依次执行。
下面给两种可行的解决方法:
方法一:用递归控制执行(推荐)
这种方式会按需创建定时器,每次执行完当前任务后,延迟2秒再判断是否继续执行下一个,能在满足条件时直接停止,不会提前创建多余的定时器。
let selects = [1,2,3,4,5,6,7,8,9]; let j = 0; function executeTask() { if (j === 5) { return; // 触发终止条件,停止执行 } console.log("loop " + j); j++; setTimeout(executeTask, 2000); } executeTask();
方法二:保存定时器ID并按需清除
如果必须保留for循环的结构,可以把所有定时器ID存到数组里,当触发终止条件时,清除所有还未执行的定时器。不过这种方式还是会先创建所有定时器,只是提前清除,效率不如递归方案。
let selects = [1,2,3,4,5,6,7,8,9]; let timers = []; for (let j = 0; j < selects.length; j++) { if (j === 5) { // 清除所有未触发的定时器 timers.forEach(timer => clearTimeout(timer)); break; } let timer = setTimeout(() => { console.log("loop " + j); }, 2000 * j); timers.push(timer); }
内容的提问来源于stack exchange,提问作者Sercan Aslan
相关产品推荐
相关产品推荐

