如何用JavaScript/JQuery将一组函数置于无限循环执行?
解决无限循环动画序列的问题
嘿,我懂你的困扰——用while(1)直接写循环肯定会把浏览器卡死,毕竟JavaScript是单线程的,同步循环会霸占主线程,让动画、定时器这些异步任务根本没机会执行!别担心,咱们用异步的方式来实现这个无限循环就好啦。
为什么while(1)不行?
JavaScript的事件循环机制决定了,同步代码会先被执行完,才会去处理异步任务(比如setTimeout、DOM动画)。while(1)是个死循环,会一直占用主线程,浏览器根本没时间处理你的动画和淡出效果,自然就卡死了。
方案1:嵌套回调实现递归循环
把你的整个动画序列封装成一个函数,每一步异步操作完成后再触发下一步,最后递归调用自己开启新的循环:
<script> function runAnim(x,y) { // 你的动画代码 } function animateLoop() { // 第一步:执行runAnim(a,2),3秒后淡出#a runAnim(a, 2); setTimeout(function() { $('#a').fadeOut('fast', function() { // #a淡出完成后,执行runAnim(b,4),3秒后淡出#b runAnim(b, 4); setTimeout(function() { $('#b').fadeOut('fast', function() { // 所有步骤完成,开启下一轮循环 animateLoop(); }); }, 3000); }); }, 3000); } // 启动循环 animateLoop(); </script>
这个写法的核心是等待上一步异步操作完成后再执行下一步,这样浏览器有足够时间处理动画,不会被阻塞。
方案2:用Async/Await简化代码(避免回调地狱)
如果觉得嵌套回调看着乱,可以用async/await配合Promise来让代码更清晰:
<script> function runAnim(x,y) { // 你的动画代码 } // 封装一个延时Promise function delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } async function animateLoop() { while(true) { // 执行第一个动画,等待3秒,再等待#a淡出完成 runAnim(a, 2); await delay(3000); await $('#a').fadeOut('fast').promise(); // 执行第二个动画,等待3秒,再等待#b淡出完成 runAnim(b, 4); await delay(3000); await $('#b').fadeOut('fast').promise(); } } // 启动循环 animateLoop(); </script>
这里的while(true)不会卡死浏览器,因为await会把控制权交还给事件循环,等异步操作完成后再继续执行下一轮。
额外提示
如果之后需要停止循环,可以加个开关变量:
let isLooping = true; async function animateLoop() { while(isLooping) { // ... 原来的代码 ... } } // 想要停止时调用 function stopLoop() { isLooping = false; }
内容的提问来源于stack exchange,提问作者AutoMate
相关产品推荐
相关产品推荐

