如何让setInterval等待另一个执行完毕?点击“one”链接实现计数器顺序执行
嘿,我来帮你搞定这两个问题!
问题1:让一个setInterval等待另一个执行完毕的通用解法
setInterval本身是周期性重复执行的,直接让它等待另一个定时器完成不太好控制。更优雅的方式是把计数器类的定时任务封装成Promise,然后用async/await来实现顺序执行——这样就能确保第一个任务完全结束后,再启动第二个任务。
举个简单的示例:
// 封装一个计数到目标值的Promise函数 function countTo(target, interval = 100) { return new Promise((resolve) => { let count = 0; const timer = setInterval(() => { count++; console.log(`当前计数:${count}`); // 达到目标值时清除定时器并resolve if (count === target) { clearInterval(timer); resolve(); } }, interval); }); } // 用async/await控制执行顺序 async function runTasksInOrder() { console.log("开始第一个计数器(到10)"); await countTo(10); // 等待第一个任务完成 console.log("第一个计数器完成,开始第二个计数器(到14)"); await countTo(14); // 再执行第二个任务 console.log("所有任务完成!"); } runTasksInOrder();
这个思路的核心是用Promise把定时器的“完成状态”暴露出来,await会自动等待Promise resolve后再执行下一行代码。
问题2:针对你的“one”链接点击事件的具体修改
结合你提供的代码,咱们需要修改progressSim()函数和点击事件逻辑,让第一个计数器(al到10)完成后,再启动第二个计数器(al2到14)。
步骤1:封装两个计数器任务为Promise
把原来的sim1_1和sim1_2逻辑分别封装成返回Promise的函数,这样就能用await控制顺序:
// 封装第一个计数器(al到10) function runFirstCounter() { return new Promise((resolve) => { al = 0; // 先清除可能存在的旧定时器 clearInterval(sim1_1); sim1_1 = setInterval(() => { al++; // 这里保留你原来的sim1_1相关UI更新逻辑(比如Canvas绘制) console.log(`第一个计数器:${al}`); if (al >= 10) { clearInterval(sim1_1); resolve(); // 第一个任务完成,通知后续代码可以执行 } }, 100); }); } // 封装第二个计数器(al2到14) function runSecondCounter() { return new Promise((resolve) => { al2 = 0; clearInterval(sim1_2); sim1_2 = setInterval(() => { al2++; // 保留你原来的sim1_2相关UI更新逻辑 console.log(`第二个计数器:${al2}`); if (al2 >= 14) { clearInterval(sim1_2); resolve(); } }, 100); }); }
步骤2:修改progressSim为async函数
让progressSim()变成异步函数,用await按顺序执行两个计数器:
async function progressSim() { // 先等待第一个计数器完成 await runFirstCounter(); // 第一个完成后,启动第二个计数器到14 await runSecondCounter(); // 如果之后还有后续逻辑,可以在这里继续添加 }
步骤3:更新点击事件调用
在点击事件里直接调用这个异步函数即可(async函数调用不需要额外处理,浏览器会自动处理异步流程):
$('a').on('click', function(e) { e.preventDefault(); jQuery('.canvasmotherwrap').hide().fadeIn(); al = 0; al2 = 0; // 清除所有可能残留的定时器 window.clearInterval(sim1_1); window.clearInterval(sim1_2); window.clearInterval(sim2); var storedata = ...; // 保留你原来的storedata相关逻辑 // 启动顺序执行的计数器任务 progressSim(); });
这样修改后,点击“one”链接时,第一个计数器会先运行到10,之后第二个计数器才会开始计数到14,完全符合你的需求。
内容的提问来源于stack exchange,提问作者Piotr
相关产品推荐
相关产品推荐

